Make dotlock.c thread-safe on pthread systems.
[gnupg.git] / common / dotlock.c
1 /* dotlock.c - dotfile locking
2  * Copyright (C) 1998, 2000, 2001, 2003, 2004,
3  *               2005, 2006, 2008, 2010, 2011 Free Software Foundation, Inc.
4  *
5  * This file is part of JNLIB, which is a subsystem of GnuPG.
6  *
7  * JNLIB is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU Lesser General Public License as
9  * published by the Free Software Foundation; either version 3 of
10  * the License, or (at your option) any later version.
11  *
12  * JNLIB is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this program; if not, see <http://www.gnu.org/licenses/>.
19  */
20
21 /*
22    Overview:
23    =========
24
25    This module implements advisory file locking in a portable way.
26    Due to the problems with POSIX fcntl locking a separate lock file
27    is used.  It would be possible to use fcntl locking on this lock
28    file and thus avoid the weird auto unlock bug of POSIX while still
29    having an unproved better performance of fcntl locking.  However
30    there are still problems left, thus we resort to use a hardlink
31    which has the well defined property that a link call will fail if
32    the target file already exists.
33
34    Given that hardlinks are also available on NTFS file systems since
35    Windows XP; it will be possible to enhance this module to use
36    hardlinks even on Windows and thus allow Windows and Posix clients
37    to use locking on the same directory.  This is not yet implemented;
38    instead we use a lockfile on Windows along with W32 style file
39    locking.
40
41    On FAT file systems hardlinks are not supported.  Thus this method
42    does not work.  Our solution is to use a O_EXCL locking instead.
43    Querying the type of the file system is not easy to do in a
44    portable way (e.g. Linux has a statfs, BSDs have a the same call
45    but using different structures and constants).  What we do instead
46    is to check at runtime whether link(2) works for a specific lock
47    file.
48
49
50    How to use:
51    ===========
52
53    At program initialization time, the module should be explicitly
54    initialized:
55
56       dotlock_create (NULL, 0);
57
58    This installs an atexit handler and may also initialize mutex etc.
59    It is optional for non-threaded applications.  Only the first call
60    has an effect.  This needs to be done before any extra threads are
61    started.
62
63    To create a lock file (which  prepares it but does not take the
64    lock) you do:
65
66      dotlock_t h
67
68      h = dotlock_create (fname, 0);
69      if (!h)
70        error ("error creating lock file: %s\n", strerror (errno));
71
72    It is important to handle the error.  For example on a read-only
73    file system a lock can't be created (but is usually not needed).
74    FNAME is the file you want to lock; the actual lockfile is that
75    name with the suffix ".lock" appended.  On success a handle to be
76    used with the other functions is returned or NULL on error.  Note
77    that the handle shall only be used by one thread at a time.  This
78    function creates a unique file temporary file (".#lk*") in the same
79    directory as FNAME and returns a handle for further operations.
80    The module keeps track of theses unique files so that they will be
81    unlinked using the atexit handler.  If you don't need the lock file
82    anymore, you may also explicitly remove it with a call to:
83
84      dotlock_destroy (h);
85
86    To actually lock the file, you use:
87
88      if (dotlock_take (h, -1))
89        error ("error taking lock: %s\n", strerror (errno));
90
91    This function will wait until the lock is acquired.  If an
92    unexpected error occurs if will return non-zero and set ERRNO.  If
93    you pass (0) instead of (-1) the function does not wait in case the
94    file is already locked but returns -1 and sets ERRNO to EACCES.
95    Any other positive value for the second parameter is considered a
96    timeout valuie in milliseconds.
97
98    To release the lock you call:
99
100      if (dotlock_release (h))
101        error ("error releasing lock: %s\n", strerror (errno));
102
103    or, if the lock file is not anymore needed, you may call
104    dotlock_destroy.
105
106    If you want to explicitly destroy all lock files you may call
107
108      dotlock_remove_lockfiles ();
109
110    which is the core of the installed atexit handler.  In case your
111    application wants to disable locking completely it may call
112
113      disable_locking ()
114
115    before any locks are created.
116
117
118    How to build:
119    =============
120
121    This module was originally developed for GnuPG but later changed to
122    allow its use without any GnuPG dependency.  If you want to use it
123    with you application you may simply use it and it should figure out
124    most things automagically.
125
126    You may use the common config.h file to pass macros, but take care
127    to pass -DHAVE_CONFIG_H to the compiler.  Macros used by this
128    module are:
129
130      DOTLOCK_USE_PTHREAD  - Define if POSIX threads are in use.
131
132      DOTLOCK_GLIB_LOGGING - Define this to use Glib logging functions.
133
134      GNUPG_MAJOR_VERSION - Defined when used by GnuPG.
135
136      HAVE_DOSISH_SYSTEM   - Defined for Windows etc.  Will be
137                             automatically defined if a the target is
138                             Windows.
139      HAVE_POSIX_SYSTEM    - Internally defined to !HAVE_DOSISH_SYSTEM.
140
141      HAVE_SIGNAL_H        - Should be defined on Posix systems.  If config.h
142                             is not used defaults to defined.
143
144      DIRSEP_C            - Separation character for file name parts.
145                            Usually not redefined.
146      EXTSEP_S "."        - Separation string for file name suffixes.
147                            Usually not redefined.
148
149      HAVE_W32CE_SYSTEM   - Currently only used by GnuPG.
150
151    Note that there is a test program t-dotlock which has compile
152    instructions at its end.  At least for SMBFS and CIFS it is
153    important that 64 bit versions of stat are used; most programming
154    environments do this these days, just in case you want to compile
155    it on the command line, remember to pass -D_FILE_OFFSET_BITS=64
156
157
158    Bugs:
159    =====
160
161    On Windows this module is not yet thread-safe.
162
163
164    Miscellaneous notes:
165    ====================
166
167    On hardlinks:
168    - Hardlinks are supported under Windows with NTFS since XP/Server2003.
169    - In Linux 2.6.33 both SMBFS and CIFS seem to support hardlinks.
170    - NFS supports hard links.  But there are solvable problems.
171    - FAT does not support links
172
173    On the file locking API:
174    - CIFS on Linux 2.6.33 supports several locking methods.
175      SMBFS seems not to support locking.  No closer checks done.
176    - NFS supports Posix locks.  flock is emulated in the server.
177      However there are a couple of problems; see below.
178    - FAT does not support locks.
179    - An advantage of fcntl locking is that R/W locks can be
180      implemented which is not easy with a straight lock file.
181
182    On O_EXCL:
183    - Does not work reliable on NFS
184    - Should work on CIFS and SMBFS but how can we delete lockfiles?
185
186    On NFS problems:
187    - Locks vanish if the server crashes and reboots.
188    - Client crashes keep the lock in the server until the client
189      re-connects.
190    - Communication problems may return unreliable error codes.  The
191      MUA Postfix's workaround is to compare the link count after
192      seeing an error for link.  However that gives a race.  If using a
193      unique file to link to a lockfile and using stat to check the
194      link count instead of looking at the error return of link(2) is
195      the best solution.
196    - O_EXCL seems to have a race and may re-create a file anyway.
197
198 */
199
200 #ifdef HAVE_CONFIG_H
201 # include <config.h>
202 #endif
203
204 /* Some quick replacements for stuff we usually expect to be defined
205    in config.h.  Define HAVE_POSIX_SYSTEM for better readability. */
206 #if !defined (HAVE_DOSISH_SYSTEM) && defined(_WIN32)
207 # define HAVE_DOSISH_SYSTEM 1
208 #endif
209 #if !defined (HAVE_DOSISH_SYSTEM) && !defined (HAVE_POSIX_SYSTEM)
210 # define HAVE_POSIX_SYSTEM 1
211 #endif
212
213 /* With no config.h assume that we have sitgnal.h.  */
214 #if !defined (HAVE_CONFIG_H) && defined (HAVE_POSIX_SYSTEM)
215 # define HAVE_SIGNAL_H 1
216 #endif
217
218 /* Standard headers.  */
219 #include <stdlib.h>
220 #include <stdio.h>
221 #include <string.h>
222 #include <errno.h>
223 #include <ctype.h>
224 #include <errno.h>
225 #include <unistd.h>
226 #ifdef  HAVE_DOSISH_SYSTEM
227 # define WIN32_LEAN_AND_MEAN  /* We only need the OS core stuff.  */
228 # include <windows.h>
229 #else
230 # include <sys/types.h>
231 # include <sys/stat.h>
232 # include <sys/utsname.h>
233 #endif
234 #include <sys/types.h>
235 #include <sys/time.h>
236 #include <sys/stat.h>
237 #include <fcntl.h>
238 #ifdef HAVE_SIGNAL_H
239 # include <signal.h>
240 #endif
241 #ifdef DOTLOCK_USE_PTHREAD
242 # include <pthread.h>
243 #endif
244
245 #ifdef DOTLOCK_GLIB_LOGGING
246 # include <glib.h>
247 #endif
248
249 #ifdef GNUPG_MAJOR_VERSION
250 # include "libjnlib-config.h"
251 #endif
252 #ifdef HAVE_W32CE_SYSTEM
253 # include "utf8conv.h"  /* WindowsCE requires filename conversion.  */
254 #endif
255
256 #include "dotlock.h"
257
258
259 /* Define constants for file name construction.  */
260 #if !defined(DIRSEP_C) && !defined(EXTSEP_S)
261 # ifdef HAVE_DOSISH_SYSTEM
262 #  define DIRSEP_C '\\'
263 #  define EXTSEP_S "."
264 #else
265 #  define DIRSEP_C '/'
266 #  define EXTSEP_S "."
267 # endif
268 #endif
269
270 /* In GnuPG we use wrappers around the malloc fucntions.  If they are
271    not defined we assume that this code is used outside of GnuPG and
272    fall back to the regular malloc functions.  */
273 #ifndef jnlib_malloc
274 # define jnlib_malloc(a)     malloc ((a))
275 # define jnlib_calloc(a,b)   calloc ((a), (b))
276 # define jnlib_free(a)       free ((a))
277 #endif
278
279 /* Wrapper to set ERRNO.  */
280 #ifndef jnlib_set_errno
281 # ifdef HAVE_W32CE_SYSTEM
282 #  define jnlib_set_errno(e)  gpg_err_set_errno ((e))
283 # else
284 #  define jnlib_set_errno(e)  do { errno = (e); } while (0)
285 # endif
286 #endif
287
288 /* Gettext macro replacement.  */
289 #ifndef _
290 # define _(a) (a)
291 #endif
292
293 #ifdef GNUPG_MAJOR_VERSION
294 # define my_info_0(a)       log_info ((a))
295 # define my_info_1(a,b)     log_info ((a), (b))
296 # define my_info_2(a,b,c)   log_info ((a), (b), (c))
297 # define my_info_3(a,b,c,d) log_info ((a), (b), (c), (d))
298 # define my_error_0(a)      log_error ((a))
299 # define my_error_1(a,b)    log_error ((a), (b))
300 # define my_error_2(a,b,c)  log_error ((a), (b), (c))
301 # define my_debug_1(a,b)    log_debug ((a), (b))
302 # define my_fatal_0(a)      log_fatal ((a))
303 #elif defined (DOTLOCK_GLIB_LOGGING)
304 # define my_info_0(a)       g_message ((a))
305 # define my_info_1(a,b)     g_message ((a), (b))
306 # define my_info_2(a,b,c)   g_message ((a), (b), (c))
307 # define my_info_3(a,b,c,d) g_message ((a), (b), (c), (d))
308 # define my_error_0(a)      g_warning ((a))
309 # define my_error_1(a,b)    g_warning ((a), (b))
310 # define my_error_2(a,b,c   g_warning ((a), (b), (c))
311 # define my_debug_1(a,b)    g_debug ((a), (b))
312 # define my_fatal_0(a)      g_error ((a))
313 #else
314 # define my_info_0(a)       fprintf (stderr, (a))
315 # define my_info_1(a,b)     fprintf (stderr, (a), (b))
316 # define my_info_2(a,b,c)   fprintf (stderr, (a), (b), (c))
317 # define my_info_3(a,b,c,d) fprintf (stderr, (a), (b), (c), (d))
318 # define my_error_0(a)      fprintf (stderr, (a))
319 # define my_error_1(a,b)    fprintf (stderr, (a), (b))
320 # define my_error_2(a,b,c)  fprintf (stderr, (a), (b), (c))
321 # define my_debug_1(a,b)    fprintf (stderr, (a), (b))
322 # define my_fatal_0(a)      do { fprintf (stderr,(a)); fflush (stderr); \
323                                  abort (); } while (0)
324 #endif
325
326
327
328
329 \f
330 /* The object describing a lock.  */
331 struct dotlock_handle
332 {
333   struct dotlock_handle *next;
334   char *lockname;            /* Name of the actual lockfile.          */
335   unsigned int locked:1;     /* Lock status.                          */
336   unsigned int disable:1;    /* If true, locking is disabled.         */
337   unsigned int use_o_excl:1; /* Use open (O_EXCL) for locking.        */
338
339 #ifdef HAVE_DOSISH_SYSTEM
340   HANDLE lockhd;       /* The W32 handle of the lock file.      */
341 #else /*!HAVE_DOSISH_SYSTEM */
342   char *tname;         /* Name of the lockfile template.        */
343   size_t nodename_off; /* Offset in TNAME of the nodename part. */
344   size_t nodename_len; /* Length of the nodename part.          */
345 #endif /*!HAVE_DOSISH_SYSTEM */
346 };
347
348
349 /* A list of of all lock handles.  The volatile attribute might help
350    if used in an atexit handler.  */
351 static volatile dotlock_t all_lockfiles;
352 #ifdef DOTLOCK_USE_PTHREAD
353 static pthread_mutex_t all_lockfiles_mutex = PTHREAD_MUTEX_INITIALIZER;
354 # define LOCK_all_lockfiles() do {                               \
355         if (pthread_mutex_lock (&all_lockfiles_mutex))           \
356           my_fatal_0 ("locking all_lockfiles_mutex failed\n");   \
357       } while (0)
358 # define UNLOCK_all_lockfiles() do {                             \
359         if (pthread_mutex_unlock (&all_lockfiles_mutex))         \
360           my_fatal_0 ("unlocking all_lockfiles_mutex failed\n"); \
361       } while (0)
362 #else  /*!DOTLOCK_USE_PTHREAD*/
363 # define LOCK_all_lockfiles()   do { } while (0)
364 # define UNLOCK_all_lockfiles() do { } while (0)
365 #endif /*!DOTLOCK_USE_PTHREAD*/
366
367 /* If this has the value true all locking is disabled.  */
368 static int never_lock;
369
370
371
372
373 \f
374 /* Entirely disable all locking.  This function should be called
375    before any locking is done.  It may be called right at startup of
376    the process as it only sets a global value.  */
377 void
378 dotlock_disable (void)
379 {
380   never_lock = 1;
381 }
382
383
384 #ifdef HAVE_POSIX_SYSTEM
385 static int
386 maybe_deadlock (dotlock_t h)
387 {
388   dotlock_t r;
389   int res = 0;
390
391   LOCK_all_lockfiles ();
392   for (r=all_lockfiles; r; r = r->next)
393     {
394       if ( r != h && r->locked )
395         {
396           res = 1;
397           break;
398         }
399     }
400   UNLOCK_all_lockfiles ();
401   return res;
402 }
403 #endif /*HAVE_POSIX_SYSTEM*/
404
405
406 /* Read the lock file and return the pid, returns -1 on error.  True
407    will be stored in the integer at address SAME_NODE if the lock file
408    has been created on the same node. */
409 #ifdef HAVE_POSIX_SYSTEM
410 static int
411 read_lockfile (dotlock_t h, int *same_node )
412 {
413   char buffer_space[10+1+70+1]; /* 70 is just an estimated value; node
414                                    names are usually shorter. */
415   int fd;
416   int pid = -1;
417   char *buffer, *p;
418   size_t expected_len;
419   int res, nread;
420
421   *same_node = 0;
422   expected_len = 10 + 1 + h->nodename_len + 1;
423   if ( expected_len >= sizeof buffer_space)
424     {
425       buffer = jnlib_malloc (expected_len);
426       if (!buffer)
427         return -1;
428     }
429   else
430     buffer = buffer_space;
431
432   if ( (fd = open (h->lockname, O_RDONLY)) == -1 )
433     {
434       int e = errno;
435       my_info_2 ("error opening lockfile `%s': %s\n",
436                  h->lockname, strerror(errno) );
437       if (buffer != buffer_space)
438         jnlib_free (buffer);
439       jnlib_set_errno (e); /* Need to return ERRNO here. */
440       return -1;
441     }
442
443   p = buffer;
444   nread = 0;
445   do
446     {
447       res = read (fd, p, expected_len - nread);
448       if (res == -1 && errno == EINTR)
449         continue;
450       if (res < 0)
451         {
452           my_info_1 ("error reading lockfile `%s'\n", h->lockname );
453           close (fd);
454           if (buffer != buffer_space)
455             jnlib_free (buffer);
456           jnlib_set_errno (0); /* Do not return an inappropriate ERRNO. */
457           return -1;
458         }
459       p += res;
460       nread += res;
461     }
462   while (res && nread != expected_len);
463   close(fd);
464
465   if (nread < 11)
466     {
467       my_info_1 ("invalid size of lockfile `%s'\n", h->lockname);
468       if (buffer != buffer_space)
469         jnlib_free (buffer);
470       jnlib_set_errno (0); /* Better don't return an inappropriate ERRNO. */
471       return -1;
472     }
473
474   if (buffer[10] != '\n'
475       || (buffer[10] = 0, pid = atoi (buffer)) == -1
476       || !pid )
477     {
478       my_error_2 ("invalid pid %d in lockfile `%s'\n", pid, h->lockname);
479       if (buffer != buffer_space)
480         jnlib_free (buffer);
481       jnlib_set_errno (0);
482       return -1;
483     }
484
485   if (nread == expected_len
486       && !memcmp (h->tname+h->nodename_off, buffer+11, h->nodename_len)
487       && buffer[11+h->nodename_len] == '\n')
488     *same_node = 1;
489
490   if (buffer != buffer_space)
491     jnlib_free (buffer);
492   return pid;
493 }
494 #endif /*HAVE_POSIX_SYSTEM */
495
496
497 /* Check whether the file system which stores TNAME supports
498    hardlinks.  Instead of using the non-portable statsfs call which
499    differs between various Unix versions, we do a runtime test.
500    Returns: 0 supports hardlinks; 1 no hardlink support, -1 unknown
501    (test error).  */
502 #ifdef HAVE_POSIX_SYSTEM
503 static int
504 use_hardlinks_p (const char *tname)
505 {
506   char *lname;
507   struct stat sb;
508   unsigned int nlink;
509   int res;
510
511   if (stat (tname, &sb))
512     return -1;
513   nlink = (unsigned int)sb.st_nlink;
514
515   lname = jnlib_malloc (strlen (tname) + 1 + 1);
516   if (!lname)
517     return -1;
518   strcpy (lname, tname);
519   strcat (lname, "x");
520
521   link (tname, lname);
522
523   if (stat (tname, &sb))
524     res = -1;  /* Ooops.  */
525   else if (sb.st_nlink == nlink + 1)
526     res = 0;   /* Yeah, hardlinks are supported.  */
527   else
528     res = 1;   /* No hardlink support.  */
529
530   unlink (lname);
531   jnlib_free (lname);
532   return res;
533 }
534 #endif /*HAVE_POSIX_SYSTEM */
535
536
537 \f
538 #ifdef  HAVE_POSIX_SYSTEM
539 /* Locking core for Unix.  It used a temporary file and the link
540    system call to make locking an atomic operation. */
541 static dotlock_t
542 dotlock_create_unix (dotlock_t h, const char *file_to_lock)
543 {
544   int  fd = -1;
545   char pidstr[16];
546   const char *nodename;
547   const char *dirpart;
548   int dirpartlen;
549   struct utsname utsbuf;
550   size_t tnamelen;
551
552   snprintf (pidstr, sizeof pidstr, "%10d\n", (int)getpid() );
553
554   /* Create a temporary file. */
555   if ( uname ( &utsbuf ) )
556     nodename = "unknown";
557   else
558     nodename = utsbuf.nodename;
559
560   if ( !(dirpart = strrchr (file_to_lock, DIRSEP_C)) )
561     {
562       dirpart = EXTSEP_S;
563       dirpartlen = 1;
564     }
565   else
566     {
567       dirpartlen = dirpart - file_to_lock;
568       dirpart = file_to_lock;
569     }
570
571   LOCK_all_lockfiles ();
572   h->next = all_lockfiles;
573   all_lockfiles = h;
574
575   tnamelen = dirpartlen + 6 + 30 + strlen(nodename) + 10 + 1;
576   h->tname = jnlib_malloc (tnamelen + 1);
577   if (!h->tname)
578     {
579       all_lockfiles = h->next;
580       UNLOCK_all_lockfiles ();
581       jnlib_free (h);
582       return NULL;
583     }
584   h->nodename_len = strlen (nodename);
585
586   snprintf (h->tname, tnamelen, "%.*s/.#lk%p.", dirpartlen, dirpart, h );
587   h->nodename_off = strlen (h->tname);
588   snprintf (h->tname+h->nodename_off, tnamelen - h->nodename_off,
589            "%s.%d", nodename, (int)getpid ());
590
591   do
592     {
593       jnlib_set_errno (0);
594       fd = open (h->tname, O_WRONLY|O_CREAT|O_EXCL,
595                  S_IRUSR|S_IRGRP|S_IROTH|S_IWUSR );
596     }
597   while (fd == -1 && errno == EINTR);
598
599   if ( fd == -1 )
600     {
601       all_lockfiles = h->next;
602       UNLOCK_all_lockfiles ();
603       my_error_2 (_("failed to create temporary file `%s': %s\n"),
604                   h->tname, strerror(errno));
605       jnlib_free (h->tname);
606       jnlib_free (h);
607       return NULL;
608     }
609   if ( write (fd, pidstr, 11 ) != 11 )
610     goto write_failed;
611   if ( write (fd, nodename, strlen (nodename) ) != strlen (nodename) )
612     goto write_failed;
613   if ( write (fd, "\n", 1 ) != 1 )
614     goto write_failed;
615   if ( close (fd) )
616     goto write_failed;
617
618   /* Check whether we support hard links.  */
619   switch (use_hardlinks_p (h->tname))
620     {
621     case 0: /* Yes.  */
622       break;
623     case 1: /* No.  */
624       unlink (h->tname);
625       h->use_o_excl = 1;
626       break;
627     default:
628       my_error_2 ("can't check whether hardlinks are supported for `%s': %s\n",
629                   h->tname, strerror(errno));
630       goto write_failed;
631     }
632
633   h->lockname = jnlib_malloc (strlen (file_to_lock) + 6 );
634   if (!h->lockname)
635     {
636       all_lockfiles = h->next;
637       UNLOCK_all_lockfiles ();
638       unlink (h->tname);
639       jnlib_free (h->tname);
640       jnlib_free (h);
641       return NULL;
642     }
643   strcpy (stpcpy (h->lockname, file_to_lock), EXTSEP_S "lock");
644   UNLOCK_all_lockfiles ();
645   if (h->use_o_excl)
646     my_debug_1 ("locking for `%s' done via O_EXCL\n", h->lockname);
647
648   return h;
649
650  write_failed:
651   all_lockfiles = h->next;
652   UNLOCK_all_lockfiles ();
653   my_error_2 (_("error writing to `%s': %s\n"), h->tname, strerror (errno));
654   close (fd);
655   unlink (h->tname);
656   jnlib_free (h->tname);
657   jnlib_free (h);
658   return NULL;
659 }
660 #endif /*HAVE_POSIX_SYSTEM*/
661
662
663 #ifdef HAVE_DOSISH_SYSTEM
664 /* Locking core for Windows.  This version does not need a temporary
665    file but uses the plain lock file along with record locking.  We
666    create this file here so that we later only need to do the file
667    locking.  For error reporting it is useful to keep the name of the
668    file in the handle.  */
669 static dotlock_t
670 dotlock_create_w32 (dotlock_t h, const char *file_to_lock)
671 {
672   LOCK_all_lockfiles ();
673   h->next = all_lockfiles;
674   all_lockfiles = h;
675
676   h->lockname = jnlib_malloc ( strlen (file_to_lock) + 6 );
677   if (!h->lockname)
678     {
679       all_lockfiles = h->next;
680       UNLOCK_all_lockfiles ();
681       jnlib_free (h);
682       return NULL;
683     }
684   strcpy (stpcpy(h->lockname, file_to_lock), EXTSEP_S "lock");
685
686   /* If would be nice if we would use the FILE_FLAG_DELETE_ON_CLOSE
687      along with FILE_SHARE_DELETE but that does not work due to a race
688      condition: Despite the OPEN_ALWAYS flag CreateFile may return an
689      error and we can't reliable create/open the lock file unless we
690      would wait here until it works - however there are other valid
691      reasons why a lock file can't be created and thus the process
692      would not stop as expected but spin until Windows crashes.  Our
693      solution is to keep the lock file open; that does not harm. */
694   {
695 #ifdef HAVE_W32CE_SYSTEM
696     wchar_t *wname = utf8_to_wchar (h->lockname);
697
698     if (wname)
699       h->lockhd = CreateFile (wname,
700                               GENERIC_READ|GENERIC_WRITE,
701                               FILE_SHARE_READ|FILE_SHARE_WRITE,
702                               NULL, OPEN_ALWAYS, 0, NULL);
703     else
704       h->lockhd = INVALID_HANDLE_VALUE;
705     jnlib_free (wname);
706 #else
707     h->lockhd = CreateFile (h->lockname,
708                             GENERIC_READ|GENERIC_WRITE,
709                             FILE_SHARE_READ|FILE_SHARE_WRITE,
710                             NULL, OPEN_ALWAYS, 0, NULL);
711 #endif
712   }
713   if (h->lockhd == INVALID_HANDLE_VALUE)
714     {
715       all_lockfiles = h->next;
716       UNLOCK_all_lockfiles ();
717       my_error_2 (_("can't create `%s': %s\n"), h->lockname, w32_strerror (-1));
718       jnlib_free (h->lockname);
719       jnlib_free (h);
720       return NULL;
721     }
722   return h;
723 }
724 #endif /*HAVE_DOSISH_SYSTEM*/
725
726
727 /* Create a lockfile for a file name FILE_TO_LOCK and returns an
728    object of type dotlock_t which may be used later to actually acquire
729    the lock.  A cleanup routine gets installed to cleanup left over
730    locks or other files used internally by the lock mechanism.
731
732    Calling this function with NULL does only install the atexit
733    handler and may thus be used to assure that the cleanup is called
734    after all other atexit handlers.
735
736    This function creates a lock file in the same directory as
737    FILE_TO_LOCK using that name and a suffix of ".lock".  Note that on
738    POSIX systems a temporary file ".#lk.<hostname>.pid[.threadid] is
739    used.
740
741    FLAGS must be 0.
742
743    The function returns an new handle which needs to be released using
744    destroy_dotlock but gets also released at the termination of the
745    process.  On error NULL is returned.
746  */
747
748 dotlock_t
749 dotlock_create (const char *file_to_lock, unsigned int flags)
750 {
751   static int initialized;
752   dotlock_t h;
753
754   if ( !initialized )
755     {
756       atexit (dotlock_remove_lockfiles);
757       initialized = 1;
758     }
759
760   if ( !file_to_lock )
761     return NULL;  /* Only initialization was requested.  */
762
763   if (flags)
764     {
765       jnlib_set_errno (EINVAL);
766       return NULL;
767     }
768
769   h = jnlib_calloc (1, sizeof *h);
770   if (!h)
771     return NULL;
772
773   if (never_lock)
774     {
775       h->disable = 1;
776       LOCK_all_lockfiles ();
777       h->next = all_lockfiles;
778       all_lockfiles = h;
779       UNLOCK_all_lockfiles ();
780       return h;
781     }
782
783 #ifdef HAVE_DOSISH_SYSTEM
784   return dotlock_create_w32 (h, file_to_lock);
785 #else /*!HAVE_DOSISH_SYSTEM */
786   return dotlock_create_unix (h, file_to_lock);
787 #endif /*!HAVE_DOSISH_SYSTEM*/
788 }
789
790
791 \f
792 #ifdef HAVE_POSIX_SYSTEM
793 /* Unix specific code of destroy_dotlock.  */
794 static void
795 dotlock_destroy_unix (dotlock_t h)
796 {
797   if (h->locked && h->lockname)
798     unlink (h->lockname);
799   if (h->tname && !h->use_o_excl)
800     unlink (h->tname);
801   jnlib_free (h->tname);
802 }
803 #endif /*HAVE_POSIX_SYSTEM*/
804
805
806 #ifdef HAVE_DOSISH_SYSTEM
807 /* Windows specific code of destroy_dotlock.  */
808 static void
809 dotlock_destroy_w32 (dotlock_t h)
810 {
811   if (h->locked)
812     {
813       OVERLAPPED ovl;
814
815       memset (&ovl, 0, sizeof ovl);
816       UnlockFileEx (h->lockhd, 0, 1, 0, &ovl);
817     }
818   CloseHandle (h->lockhd);
819 }
820 #endif /*HAVE_DOSISH_SYSTEM*/
821
822
823 /* Destroy the locck handle H and release the lock.  */
824 void
825 dotlock_destroy (dotlock_t h)
826 {
827   dotlock_t hprev, htmp;
828
829   if ( !h )
830     return;
831
832   /* First remove the handle from our global list of all locks. */
833   LOCK_all_lockfiles ();
834   for (hprev=NULL, htmp=all_lockfiles; htmp; hprev=htmp, htmp=htmp->next)
835     if (htmp == h)
836       {
837         if (hprev)
838           hprev->next = htmp->next;
839         else
840           all_lockfiles = htmp->next;
841         h->next = NULL;
842         break;
843       }
844   UNLOCK_all_lockfiles ();
845
846   /* Then destroy the lock. */
847   if (!h->disable)
848     {
849 #ifdef HAVE_DOSISH_SYSTEM
850       dotlock_destroy_w32 (h);
851 #else /* !HAVE_DOSISH_SYSTEM */
852       dotlock_destroy_unix (h);
853 #endif /* HAVE_DOSISH_SYSTEM */
854       jnlib_free (h->lockname);
855     }
856   jnlib_free(h);
857 }
858
859
860 \f
861 #ifdef HAVE_POSIX_SYSTEM
862 /* Unix specific code of make_dotlock.  Returns 0 on success and -1 on
863    error.  */
864 static int
865 dotlock_take_unix (dotlock_t h, long timeout)
866 {
867   int wtime = 0;
868   int sumtime = 0;
869   int pid;
870   int lastpid = -1;
871   int ownerchanged;
872   const char *maybe_dead="";
873   int same_node;
874
875  again:
876   if (h->use_o_excl)
877     {
878       /* No hardlink support - use open(O_EXCL).  */
879       int fd;
880
881       do
882         {
883           jnlib_set_errno (0);
884           fd = open (h->lockname, O_WRONLY|O_CREAT|O_EXCL,
885                      S_IRUSR|S_IRGRP|S_IROTH|S_IWUSR );
886         }
887       while (fd == -1 && errno == EINTR);
888
889       if (fd == -1 && errno == EEXIST)
890         ; /* Lock held by another process.  */
891       else if (fd == -1)
892         {
893           my_error_2 ("lock not made: open(O_EXCL) of `%s' failed: %s\n",
894                       h->lockname, strerror (errno));
895           return -1;
896         }
897       else
898         {
899           char pidstr[16];
900
901           snprintf (pidstr, sizeof pidstr, "%10d\n", (int)getpid());
902           if (write (fd, pidstr, 11 ) == 11
903               && write (fd, h->tname + h->nodename_off,h->nodename_len)
904               == h->nodename_len
905               && write (fd, "\n", 1) == 1
906               && !close (fd))
907             {
908               h->locked = 1;
909               return 0;
910             }
911           /* Write error.  */
912           my_error_2 ("lock not made: writing to `%s' failed: %s\n",
913                       h->lockname, strerror (errno));
914           close (fd);
915           unlink (h->lockname);
916           return -1;
917         }
918     }
919   else /* Standard method:  Use hardlinks.  */
920     {
921       struct stat sb;
922
923       link (h->tname, h->lockname);
924
925       if (stat (h->tname, &sb))
926         {
927           my_error_1 ("lock not made: Oops: stat of tmp file failed: %s\n",
928                       strerror (errno));
929           /* In theory this might be a severe error: It is possible
930              that link succeeded but stat failed due to changed
931              permissions.  We can't do anything about it, though.  */
932           return -1;
933         }
934
935       if (sb.st_nlink == 2)
936         {
937           h->locked = 1;
938           return 0; /* Okay.  */
939         }
940     }
941
942   /* Check for stale lock files.  */
943   if ( (pid = read_lockfile (h, &same_node)) == -1 )
944     {
945       if ( errno != ENOENT )
946         {
947           my_info_0 ("cannot read lockfile\n");
948           return -1;
949         }
950       my_info_0 ("lockfile disappeared\n");
951       goto again;
952     }
953   else if ( pid == getpid() && same_node )
954     {
955       my_info_0 ("Oops: lock already held by us\n");
956       h->locked = 1;
957       return 0; /* okay */
958     }
959   else if ( same_node && kill (pid, 0) && errno == ESRCH )
960     {
961       /* Note: It is unlikley that we get a race here unless a pid is
962          reused too fast or a new process with the same pid as the one
963          of the stale file tries to lock right at the same time as we.  */
964       my_info_1 (_("removing stale lockfile (created by %d)\n"), pid);
965       unlink (h->lockname);
966       goto again;
967     }
968
969   if (lastpid == -1)
970     lastpid = pid;
971   ownerchanged = (pid != lastpid);
972
973   if (timeout)
974     {
975       struct timeval tv;
976
977       /* Wait until lock has been released.  We use increasing retry
978          intervals of 50ms, 100ms, 200ms, 400ms, 800ms, 2s, 4s and 8s
979          but reset it if the lock owner meanwhile changed.  */
980       if (!wtime || ownerchanged)
981         wtime = 50;
982       else if (wtime < 800)
983         wtime *= 2;
984       else if (wtime == 800)
985         wtime = 2000;
986       else if (wtime < 8000)
987         wtime *= 2;
988
989       if (timeout > 0)
990         {
991           if (wtime > timeout)
992             wtime = timeout;
993           timeout -= wtime;
994         }
995
996       sumtime += wtime;
997       if (sumtime >= 1500)
998         {
999           sumtime = 0;
1000           my_info_3 (_("waiting for lock (held by %d%s) %s...\n"),
1001                      pid, maybe_dead, maybe_deadlock(h)? _("(deadlock?) "):"");
1002         }
1003
1004
1005       tv.tv_sec = wtime / 1000;
1006       tv.tv_usec = (wtime % 1000) * 1000;
1007       select (0, NULL, NULL, NULL, &tv);
1008       goto again;
1009     }
1010
1011   jnlib_set_errno (EACCES);
1012   return -1;
1013 }
1014 #endif /*HAVE_POSIX_SYSTEM*/
1015
1016
1017 #ifdef HAVE_DOSISH_SYSTEM
1018 /* Windows specific code of make_dotlock.  Returns 0 on success and -1 on
1019    error.  */
1020 static int
1021 dotlock_take_w32 (dotlock_t h, long timeout)
1022 {
1023   int wtime = 0;
1024   int w32err;
1025   OVERLAPPED ovl;
1026
1027  again:
1028   /* Lock one byte at offset 0.  The offset is given by OVL.  */
1029   memset (&ovl, 0, sizeof ovl);
1030   if (LockFileEx (h->lockhd, (LOCKFILE_EXCLUSIVE_LOCK
1031                               | LOCKFILE_FAIL_IMMEDIATELY), 0, 1, 0, &ovl))
1032     {
1033       h->locked = 1;
1034       return 0; /* okay */
1035     }
1036
1037   w32err = GetLastError ();
1038   if (w32err != ERROR_LOCK_VIOLATION)
1039     {
1040       my_error_2 (_("lock `%s' not made: %s\n"),
1041                   h->lockname, w32_strerror (w32err));
1042       return -1;
1043     }
1044
1045   if (timeout)
1046     {
1047       /* Wait until lock has been released.  We use retry intervals of
1048          50ms, 100ms, 200ms, 400ms, 800ms, 2s, 4s and 8s.  */
1049       if (!wtime)
1050         wtime = 50;
1051       else if (wtime < 800)
1052         wtime *= 2;
1053       else if (wtime == 800)
1054         wtime = 2000;
1055       else if (wtime < 8000)
1056         wtime *= 2;
1057
1058       if (timeout > 0)
1059         {
1060           if (wtime > timeout)
1061             wtime = timeout;
1062           timeout -= wtime;
1063         }
1064
1065       if (wtime >= 800)
1066         my_info_1 (_("waiting for lock %s...\n"), h->lockname);
1067
1068       Sleep (wtime);
1069       goto again;
1070     }
1071
1072   return -1;
1073 }
1074 #endif /*HAVE_DOSISH_SYSTEM*/
1075
1076
1077 /* Take a lock on H.  A value of 0 for TIMEOUT returns immediately if
1078    the lock can't be taked, -1 waits forever (hopefully not), other
1079    values wait for TIMEOUT milliseconds.  Returns: 0 on success  */
1080 int
1081 dotlock_take (dotlock_t h, long timeout)
1082 {
1083   int ret;
1084
1085   if ( h->disable )
1086     return 0; /* Locks are completely disabled.  Return success. */
1087
1088   if ( h->locked )
1089     {
1090       my_debug_1 ("Oops, `%s' is already locked\n", h->lockname);
1091       return 0;
1092     }
1093
1094 #ifdef HAVE_DOSISH_SYSTEM
1095   ret = dotlock_take_w32 (h, timeout);
1096 #else /*!HAVE_DOSISH_SYSTEM*/
1097   ret = dotlock_take_unix (h, timeout);
1098 #endif /*!HAVE_DOSISH_SYSTEM*/
1099
1100   return ret;
1101 }
1102
1103
1104 \f
1105 #ifdef HAVE_POSIX_SYSTEM
1106 /* Unix specific code of release_dotlock.  */
1107 static int
1108 dotlock_release_unix (dotlock_t h)
1109 {
1110   int pid, same_node;
1111
1112   pid = read_lockfile (h, &same_node);
1113   if ( pid == -1 )
1114     {
1115       my_error_0 ("release_dotlock: lockfile error\n");
1116       return -1;
1117     }
1118   if ( pid != getpid() || !same_node )
1119     {
1120       my_error_1 ("release_dotlock: not our lock (pid=%d)\n", pid);
1121       return -1;
1122     }
1123
1124   if ( unlink( h->lockname ) )
1125     {
1126       my_error_1 ("release_dotlock: error removing lockfile `%s'\n",
1127                   h->lockname);
1128       return -1;
1129     }
1130   /* Fixme: As an extra check we could check whether the link count is
1131      now really at 1. */
1132   return 0;
1133 }
1134 #endif /*HAVE_POSIX_SYSTEM */
1135
1136
1137 #ifdef HAVE_DOSISH_SYSTEM
1138 /* Windows specific code of release_dotlock.  */
1139 static int
1140 dotlock_release_w32 (dotlock_t h)
1141 {
1142   OVERLAPPED ovl;
1143
1144   memset (&ovl, 0, sizeof ovl);
1145   if (!UnlockFileEx (h->lockhd, 0, 1, 0, &ovl))
1146     {
1147       my_error_2 ("release_dotlock: error removing lockfile `%s': %s\n",
1148                   h->lockname, w32_strerror (-1));
1149       return -1;
1150     }
1151
1152   return 0;
1153 }
1154 #endif /*HAVE_DOSISH_SYSTEM */
1155
1156
1157 /* Release a lock.  Returns 0 on success.  */
1158 int
1159 dotlock_release (dotlock_t h)
1160 {
1161   int ret;
1162
1163   /* To avoid atexit race conditions we first check whether there are
1164      any locks left.  It might happen that another atexit handler
1165      tries to release the lock while the atexit handler of this module
1166      already ran and thus H is undefined.  */
1167   LOCK_all_lockfiles ();
1168   ret = !all_lockfiles;
1169   UNLOCK_all_lockfiles ();
1170   if (ret)
1171     return 0;
1172
1173   if ( h->disable )
1174     return 0;
1175
1176   if ( !h->locked )
1177     {
1178       my_debug_1 ("Oops, `%s' is not locked\n", h->lockname);
1179       return 0;
1180     }
1181
1182 #ifdef HAVE_DOSISH_SYSTEM
1183   ret = dotlock_release_w32 (h);
1184 #else
1185   ret = dotlock_release_unix (h);
1186 #endif
1187
1188   if (!ret)
1189     h->locked = 0;
1190   return ret;
1191 }
1192
1193
1194 \f
1195 /* Remove all lockfiles.  This is called by the atexit handler
1196    installed by this module but may also be called by other
1197    termination handlers.  */
1198 void
1199 dotlock_remove_lockfiles (void)
1200 {
1201   dotlock_t h, h2;
1202
1203   /* First set the lockfiles list to NULL so that for example
1204      dotlock_release is ware that this fucntion is currently
1205      running.  */
1206   LOCK_all_lockfiles ();
1207   h = all_lockfiles;
1208   all_lockfiles = NULL;
1209   UNLOCK_all_lockfiles ();
1210
1211   while ( h )
1212     {
1213       h2 = h->next;
1214       dotlock_destroy (h);
1215       h = h2;
1216     }
1217 }