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