chiark / gitweb /
gpg agent lockup fix: Interrupt main loop when active_connections_value==0
[gnupg2.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 GnuPG.
6  *
7  * GnuPG 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  * GnuPG 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 <https://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 # include "util.h"
314 # include "common-defs.h"
315 # include "stringhelp.h"  /* For stpcpy and w32_strerror. */
316 #endif
317 #ifdef HAVE_W32CE_SYSTEM
318 # include "utf8conv.h"  /* WindowsCE requires filename conversion.  */
319 #endif
320
321 #include "dotlock.h"
322
323
324 /* Define constants for file name construction.  */
325 #if !defined(DIRSEP_C) && !defined(EXTSEP_S)
326 # ifdef HAVE_DOSISH_SYSTEM
327 #  define DIRSEP_C '\\'
328 #  define EXTSEP_S "."
329 #else
330 #  define DIRSEP_C '/'
331 #  define EXTSEP_S "."
332 # endif
333 #endif
334
335 /* In GnuPG we use wrappers around the malloc fucntions.  If they are
336    not defined we assume that this code is used outside of GnuPG and
337    fall back to the regular malloc functions.  */
338 #ifndef xtrymalloc
339 # define xtrymalloc(a)     malloc ((a))
340 # define xtrycalloc(a,b)   calloc ((a), (b))
341 # define xfree(a)          free ((a))
342 #endif
343
344 /* Wrapper to set ERRNO (required for W32CE).  */
345 #ifdef GPG_ERROR_VERSION
346 #  define my_set_errno(e)  gpg_err_set_errno ((e))
347 #else
348 #  define my_set_errno(e)  do { errno = (e); } while (0)
349 #endif
350
351 /* Gettext macro replacement.  */
352 #ifndef _
353 # define _(a) (a)
354 #endif
355
356 #ifdef GNUPG_MAJOR_VERSION
357 # define my_info_0(a)       log_info ((a))
358 # define my_info_1(a,b)     log_info ((a), (b))
359 # define my_info_2(a,b,c)   log_info ((a), (b), (c))
360 # define my_info_3(a,b,c,d) log_info ((a), (b), (c), (d))
361 # define my_error_0(a)      log_error ((a))
362 # define my_error_1(a,b)    log_error ((a), (b))
363 # define my_error_2(a,b,c)  log_error ((a), (b), (c))
364 # define my_debug_1(a,b)    log_debug ((a), (b))
365 # define my_fatal_0(a)      log_fatal ((a))
366 #elif defined (DOTLOCK_GLIB_LOGGING)
367 # define my_info_0(a)       g_message ((a))
368 # define my_info_1(a,b)     g_message ((a), (b))
369 # define my_info_2(a,b,c)   g_message ((a), (b), (c))
370 # define my_info_3(a,b,c,d) g_message ((a), (b), (c), (d))
371 # define my_error_0(a)      g_warning ((a))
372 # define my_error_1(a,b)    g_warning ((a), (b))
373 # define my_error_2(a,b,c)  g_warning ((a), (b), (c))
374 # define my_debug_1(a,b)    g_debug ((a), (b))
375 # define my_fatal_0(a)      g_error ((a))
376 #else
377 # define my_info_0(a)       fprintf (stderr, (a))
378 # define my_info_1(a,b)     fprintf (stderr, (a), (b))
379 # define my_info_2(a,b,c)   fprintf (stderr, (a), (b), (c))
380 # define my_info_3(a,b,c,d) fprintf (stderr, (a), (b), (c), (d))
381 # define my_error_0(a)      fprintf (stderr, (a))
382 # define my_error_1(a,b)    fprintf (stderr, (a), (b))
383 # define my_error_2(a,b,c)  fprintf (stderr, (a), (b), (c))
384 # define my_debug_1(a,b)    fprintf (stderr, (a), (b))
385 # define my_fatal_0(a)      do { fprintf (stderr,(a)); fflush (stderr); \
386                                  abort (); } while (0)
387 #endif
388
389
390
391
392 \f
393 /* The object describing a lock.  */
394 struct dotlock_handle
395 {
396   struct dotlock_handle *next;
397   char *lockname;            /* Name of the actual lockfile.          */
398   unsigned int locked:1;     /* Lock status.                          */
399   unsigned int disable:1;    /* If true, locking is disabled.         */
400   unsigned int use_o_excl:1; /* Use open (O_EXCL) for locking.        */
401
402   int extra_fd;              /* A place for the caller to store an FD.  */
403
404 #ifdef HAVE_DOSISH_SYSTEM
405   HANDLE lockhd;       /* The W32 handle of the lock file.      */
406 #else /*!HAVE_DOSISH_SYSTEM */
407   char *tname;         /* Name of the lockfile template.        */
408   size_t nodename_off; /* Offset in TNAME of the nodename part. */
409   size_t nodename_len; /* Length of the nodename part.          */
410 #endif /*!HAVE_DOSISH_SYSTEM */
411 };
412
413
414 /* A list of of all lock handles.  The volatile attribute might help
415    if used in an atexit handler.  Note that [UN]LOCK_all_lockfiles
416    must not change ERRNO. */
417 static volatile dotlock_t all_lockfiles;
418 #ifdef DOTLOCK_USE_PTHREAD
419 static pthread_mutex_t all_lockfiles_mutex = PTHREAD_MUTEX_INITIALIZER;
420 # define LOCK_all_lockfiles() do {                               \
421         if (pthread_mutex_lock (&all_lockfiles_mutex))           \
422           my_fatal_0 ("locking all_lockfiles_mutex failed\n");   \
423       } while (0)
424 # define UNLOCK_all_lockfiles() do {                             \
425         if (pthread_mutex_unlock (&all_lockfiles_mutex))         \
426           my_fatal_0 ("unlocking all_lockfiles_mutex failed\n"); \
427       } while (0)
428 #else  /*!DOTLOCK_USE_PTHREAD*/
429 # define LOCK_all_lockfiles()   do { } while (0)
430 # define UNLOCK_all_lockfiles() do { } while (0)
431 #endif /*!DOTLOCK_USE_PTHREAD*/
432
433 /* If this has the value true all locking is disabled.  */
434 static int never_lock;
435
436
437
438 \f
439 #ifdef HAVE_DOSISH_SYSTEM
440 static int
441 map_w32_to_errno (DWORD w32_err)
442 {
443   switch (w32_err)
444     {
445     case 0:
446       return 0;
447
448     case ERROR_FILE_NOT_FOUND:
449       return ENOENT;
450
451     case ERROR_PATH_NOT_FOUND:
452       return ENOENT;
453
454     case ERROR_ACCESS_DENIED:
455       return EPERM;
456
457     case ERROR_INVALID_HANDLE:
458     case ERROR_INVALID_BLOCK:
459       return EINVAL;
460
461     case ERROR_NOT_ENOUGH_MEMORY:
462       return ENOMEM;
463
464     case ERROR_NO_DATA:
465     case ERROR_BROKEN_PIPE:
466       return EPIPE;
467
468     default:
469       return EIO;
470     }
471 }
472 #endif /*HAVE_DOSISH_SYSTEM*/
473
474 \f
475 /* Entirely disable all locking.  This function should be called
476    before any locking is done.  It may be called right at startup of
477    the process as it only sets a global value.  */
478 void
479 dotlock_disable (void)
480 {
481   never_lock = 1;
482 }
483
484
485 #ifdef HAVE_POSIX_SYSTEM
486 static int
487 maybe_deadlock (dotlock_t h)
488 {
489   dotlock_t r;
490   int res = 0;
491
492   LOCK_all_lockfiles ();
493   for (r=all_lockfiles; r; r = r->next)
494     {
495       if ( r != h && r->locked )
496         {
497           res = 1;
498           break;
499         }
500     }
501   UNLOCK_all_lockfiles ();
502   return res;
503 }
504 #endif /*HAVE_POSIX_SYSTEM*/
505
506
507 /* Read the lock file and return the pid, returns -1 on error.  True
508    will be stored in the integer at address SAME_NODE if the lock file
509    has been created on the same node. */
510 #ifdef HAVE_POSIX_SYSTEM
511 static int
512 read_lockfile (dotlock_t h, int *same_node )
513 {
514   char buffer_space[10+1+70+1]; /* 70 is just an estimated value; node
515                                    names are usually shorter. */
516   int fd;
517   int pid = -1;
518   char *buffer, *p;
519   size_t expected_len;
520   int res, nread;
521
522   *same_node = 0;
523   expected_len = 10 + 1 + h->nodename_len + 1;
524   if ( expected_len >= sizeof buffer_space)
525     {
526       buffer = xtrymalloc (expected_len);
527       if (!buffer)
528         return -1;
529     }
530   else
531     buffer = buffer_space;
532
533   if ( (fd = open (h->lockname, O_RDONLY)) == -1 )
534     {
535       int e = errno;
536       my_info_2 ("error opening lockfile '%s': %s\n",
537                  h->lockname, strerror(errno) );
538       if (buffer != buffer_space)
539         xfree (buffer);
540       my_set_errno (e); /* Need to return ERRNO here. */
541       return -1;
542     }
543
544   p = buffer;
545   nread = 0;
546   do
547     {
548       res = read (fd, p, expected_len - nread);
549       if (res == -1 && errno == EINTR)
550         continue;
551       if (res < 0)
552         {
553           int e = errno;
554           my_info_1 ("error reading lockfile '%s'\n", h->lockname );
555           close (fd);
556           if (buffer != buffer_space)
557             xfree (buffer);
558           my_set_errno (e);
559           return -1;
560         }
561       p += res;
562       nread += res;
563     }
564   while (res && nread != expected_len);
565   close(fd);
566
567   if (nread < 11)
568     {
569       my_info_1 ("invalid size of lockfile '%s'\n", h->lockname);
570       if (buffer != buffer_space)
571         xfree (buffer);
572       my_set_errno (EINVAL);
573       return -1;
574     }
575
576   if (buffer[10] != '\n'
577       || (buffer[10] = 0, pid = atoi (buffer)) == -1
578       || !pid )
579     {
580       my_error_2 ("invalid pid %d in lockfile '%s'\n", pid, h->lockname);
581       if (buffer != buffer_space)
582         xfree (buffer);
583       my_set_errno (EINVAL);
584       return -1;
585     }
586
587   if (nread == expected_len
588       && !memcmp (h->tname+h->nodename_off, buffer+11, h->nodename_len)
589       && buffer[11+h->nodename_len] == '\n')
590     *same_node = 1;
591
592   if (buffer != buffer_space)
593     xfree (buffer);
594   return pid;
595 }
596 #endif /*HAVE_POSIX_SYSTEM */
597
598
599 /* Check whether the file system which stores TNAME supports
600    hardlinks.  Instead of using the non-portable statsfs call which
601    differs between various Unix versions, we do a runtime test.
602    Returns: 0 supports hardlinks; 1 no hardlink support, -1 unknown
603    (test error).  */
604 #ifdef HAVE_POSIX_SYSTEM
605 static int
606 use_hardlinks_p (const char *tname)
607 {
608   char *lname;
609   struct stat sb;
610   unsigned int nlink;
611   int res;
612
613   if (stat (tname, &sb))
614     return -1;
615   nlink = (unsigned int)sb.st_nlink;
616
617   lname = xtrymalloc (strlen (tname) + 1 + 1);
618   if (!lname)
619     return -1;
620   strcpy (lname, tname);
621   strcat (lname, "x");
622
623   /* We ignore the return value of link() because it is unreliable.  */
624   (void) link (tname, lname);
625
626   if (stat (tname, &sb))
627     res = -1;  /* Ooops.  */
628   else if (sb.st_nlink == nlink + 1)
629     res = 0;   /* Yeah, hardlinks are supported.  */
630   else
631     res = 1;   /* No hardlink support.  */
632
633   unlink (lname);
634   xfree (lname);
635   return res;
636 }
637 #endif /*HAVE_POSIX_SYSTEM */
638
639
640 \f
641 #ifdef  HAVE_POSIX_SYSTEM
642 /* Locking core for Unix.  It used a temporary file and the link
643    system call to make locking an atomic operation. */
644 static dotlock_t
645 dotlock_create_unix (dotlock_t h, const char *file_to_lock)
646 {
647   int  fd = -1;
648   char pidstr[16];
649   const char *nodename;
650   const char *dirpart;
651   int dirpartlen;
652   struct utsname utsbuf;
653   size_t tnamelen;
654
655   snprintf (pidstr, sizeof pidstr, "%10d\n", (int)getpid() );
656
657   /* Create a temporary file. */
658   if ( uname ( &utsbuf ) )
659     nodename = "unknown";
660   else
661     nodename = utsbuf.nodename;
662
663   if ( !(dirpart = strrchr (file_to_lock, DIRSEP_C)) )
664     {
665       dirpart = EXTSEP_S;
666       dirpartlen = 1;
667     }
668   else
669     {
670       dirpartlen = dirpart - file_to_lock;
671       dirpart = file_to_lock;
672     }
673
674   LOCK_all_lockfiles ();
675   h->next = all_lockfiles;
676   all_lockfiles = h;
677
678   tnamelen = dirpartlen + 6 + 30 + strlen(nodename) + 10 + 1;
679   h->tname = xtrymalloc (tnamelen + 1);
680   if (!h->tname)
681     {
682       all_lockfiles = h->next;
683       UNLOCK_all_lockfiles ();
684       xfree (h);
685       return NULL;
686     }
687   h->nodename_len = strlen (nodename);
688
689   snprintf (h->tname, tnamelen, "%.*s/.#lk%p.", dirpartlen, dirpart, h );
690   h->nodename_off = strlen (h->tname);
691   snprintf (h->tname+h->nodename_off, tnamelen - h->nodename_off,
692            "%s.%d", nodename, (int)getpid ());
693
694   do
695     {
696       my_set_errno (0);
697       fd = open (h->tname, O_WRONLY|O_CREAT|O_EXCL,
698                  S_IRUSR|S_IRGRP|S_IROTH|S_IWUSR );
699     }
700   while (fd == -1 && errno == EINTR);
701
702   if ( fd == -1 )
703     {
704       int saveerrno = errno;
705       all_lockfiles = h->next;
706       UNLOCK_all_lockfiles ();
707       my_error_2 (_("failed to create temporary file '%s': %s\n"),
708                   h->tname, strerror (errno));
709       xfree (h->tname);
710       xfree (h);
711       my_set_errno (saveerrno);
712       return NULL;
713     }
714   if ( write (fd, pidstr, 11 ) != 11 )
715     goto write_failed;
716   if ( write (fd, nodename, strlen (nodename) ) != strlen (nodename) )
717     goto write_failed;
718   if ( write (fd, "\n", 1 ) != 1 )
719     goto write_failed;
720   if ( close (fd) )
721     {
722       if ( errno == EINTR )
723         fd = -1;
724       goto write_failed;
725     }
726   fd = -1;
727
728   /* Check whether we support hard links.  */
729   switch (use_hardlinks_p (h->tname))
730     {
731     case 0: /* Yes.  */
732       break;
733     case 1: /* No.  */
734       unlink (h->tname);
735       h->use_o_excl = 1;
736       break;
737     default:
738       {
739         int saveerrno = errno;
740         my_error_2 ("can't check whether hardlinks are supported for '%s': %s\n"
741                     , h->tname, strerror (saveerrno));
742         my_set_errno (saveerrno);
743       }
744       goto write_failed;
745     }
746
747   h->lockname = xtrymalloc (strlen (file_to_lock) + 6 );
748   if (!h->lockname)
749     {
750       int saveerrno = errno;
751       all_lockfiles = h->next;
752       UNLOCK_all_lockfiles ();
753       unlink (h->tname);
754       xfree (h->tname);
755       xfree (h);
756       my_set_errno (saveerrno);
757       return NULL;
758     }
759   strcpy (stpcpy (h->lockname, file_to_lock), EXTSEP_S "lock");
760   UNLOCK_all_lockfiles ();
761   if (h->use_o_excl)
762     my_debug_1 ("locking for '%s' done via O_EXCL\n", h->lockname);
763
764   return h;
765
766  write_failed:
767   {
768     int saveerrno = errno;
769     all_lockfiles = h->next;
770     UNLOCK_all_lockfiles ();
771     my_error_2 (_("error writing to '%s': %s\n"), h->tname, strerror (errno));
772     if ( fd != -1 )
773       close (fd);
774     unlink (h->tname);
775     xfree (h->tname);
776     xfree (h);
777     my_set_errno (saveerrno);
778   }
779   return NULL;
780 }
781 #endif /*HAVE_POSIX_SYSTEM*/
782
783
784 #ifdef HAVE_DOSISH_SYSTEM
785 /* Locking core for Windows.  This version does not need a temporary
786    file but uses the plain lock file along with record locking.  We
787    create this file here so that we later only need to do the file
788    locking.  For error reporting it is useful to keep the name of the
789    file in the handle.  */
790 static dotlock_t
791 dotlock_create_w32 (dotlock_t h, const char *file_to_lock)
792 {
793   LOCK_all_lockfiles ();
794   h->next = all_lockfiles;
795   all_lockfiles = h;
796
797   h->lockname = xtrymalloc ( strlen (file_to_lock) + 6 );
798   if (!h->lockname)
799     {
800       all_lockfiles = h->next;
801       UNLOCK_all_lockfiles ();
802       xfree (h);
803       return NULL;
804     }
805   strcpy (stpcpy(h->lockname, file_to_lock), EXTSEP_S "lock");
806
807   /* If would be nice if we would use the FILE_FLAG_DELETE_ON_CLOSE
808      along with FILE_SHARE_DELETE but that does not work due to a race
809      condition: Despite the OPEN_ALWAYS flag CreateFile may return an
810      error and we can't reliable create/open the lock file unless we
811      would wait here until it works - however there are other valid
812      reasons why a lock file can't be created and thus the process
813      would not stop as expected but spin until Windows crashes.  Our
814      solution is to keep the lock file open; that does not harm. */
815   {
816 #ifdef HAVE_W32CE_SYSTEM
817     wchar_t *wname = utf8_to_wchar (h->lockname);
818
819     if (wname)
820       h->lockhd = CreateFile (wname,
821                               GENERIC_READ|GENERIC_WRITE,
822                               FILE_SHARE_READ|FILE_SHARE_WRITE,
823                               NULL, OPEN_ALWAYS, 0, NULL);
824     else
825       h->lockhd = INVALID_HANDLE_VALUE;
826     xfree (wname);
827 #else
828     h->lockhd = CreateFile (h->lockname,
829                             GENERIC_READ|GENERIC_WRITE,
830                             FILE_SHARE_READ|FILE_SHARE_WRITE,
831                             NULL, OPEN_ALWAYS, 0, NULL);
832 #endif
833   }
834   if (h->lockhd == INVALID_HANDLE_VALUE)
835     {
836       int saveerrno = map_w32_to_errno (GetLastError ());
837       all_lockfiles = h->next;
838       UNLOCK_all_lockfiles ();
839       my_error_2 (_("can't create '%s': %s\n"), h->lockname, w32_strerror (-1));
840       xfree (h->lockname);
841       xfree (h);
842       my_set_errno (saveerrno);
843       return NULL;
844     }
845   return h;
846 }
847 #endif /*HAVE_DOSISH_SYSTEM*/
848
849
850 /* Create a lockfile for a file name FILE_TO_LOCK and returns an
851    object of type dotlock_t which may be used later to actually acquire
852    the lock.  A cleanup routine gets installed to cleanup left over
853    locks or other files used internally by the lock mechanism.
854
855    Calling this function with NULL does only install the atexit
856    handler and may thus be used to assure that the cleanup is called
857    after all other atexit handlers.
858
859    This function creates a lock file in the same directory as
860    FILE_TO_LOCK using that name and a suffix of ".lock".  Note that on
861    POSIX systems a temporary file ".#lk.<hostname>.pid[.threadid] is
862    used.
863
864    FLAGS must be 0.
865
866    The function returns an new handle which needs to be released using
867    destroy_dotlock but gets also released at the termination of the
868    process.  On error NULL is returned.
869  */
870
871 dotlock_t
872 dotlock_create (const char *file_to_lock, unsigned int flags)
873 {
874   static int initialized;
875   dotlock_t h;
876
877   if ( !initialized )
878     {
879       atexit (dotlock_remove_lockfiles);
880       initialized = 1;
881     }
882
883   if ( !file_to_lock )
884     return NULL;  /* Only initialization was requested.  */
885
886   if (flags)
887     {
888       my_set_errno (EINVAL);
889       return NULL;
890     }
891
892   h = xtrycalloc (1, sizeof *h);
893   if (!h)
894     return NULL;
895   h->extra_fd = -1;
896
897   if (never_lock)
898     {
899       h->disable = 1;
900       LOCK_all_lockfiles ();
901       h->next = all_lockfiles;
902       all_lockfiles = h;
903       UNLOCK_all_lockfiles ();
904       return h;
905     }
906
907 #ifdef HAVE_DOSISH_SYSTEM
908   return dotlock_create_w32 (h, file_to_lock);
909 #else /*!HAVE_DOSISH_SYSTEM */
910   return dotlock_create_unix (h, file_to_lock);
911 #endif /*!HAVE_DOSISH_SYSTEM*/
912 }
913
914
915 \f
916 /* Convenience function to store a file descriptor (or any any other
917    integer value) in the context of handle H.  */
918 void
919 dotlock_set_fd (dotlock_t h, int fd)
920 {
921   h->extra_fd = fd;
922 }
923
924 /* Convenience function to retrieve a file descriptor (or any any other
925    integer value) stored in the context of handle H.  */
926 int
927 dotlock_get_fd (dotlock_t h)
928 {
929   return h->extra_fd;
930 }
931
932
933 \f
934 #ifdef HAVE_POSIX_SYSTEM
935 /* Unix specific code of destroy_dotlock.  */
936 static void
937 dotlock_destroy_unix (dotlock_t h)
938 {
939   if (h->locked && h->lockname)
940     unlink (h->lockname);
941   if (h->tname && !h->use_o_excl)
942     unlink (h->tname);
943   xfree (h->tname);
944 }
945 #endif /*HAVE_POSIX_SYSTEM*/
946
947
948 #ifdef HAVE_DOSISH_SYSTEM
949 /* Windows specific code of destroy_dotlock.  */
950 static void
951 dotlock_destroy_w32 (dotlock_t h)
952 {
953   if (h->locked)
954     {
955       OVERLAPPED ovl;
956
957       memset (&ovl, 0, sizeof ovl);
958       UnlockFileEx (h->lockhd, 0, 1, 0, &ovl);
959     }
960   CloseHandle (h->lockhd);
961 }
962 #endif /*HAVE_DOSISH_SYSTEM*/
963
964
965 /* Destroy the lock handle H and release the lock.  */
966 void
967 dotlock_destroy (dotlock_t h)
968 {
969   dotlock_t hprev, htmp;
970
971   if ( !h )
972     return;
973
974   /* First remove the handle from our global list of all locks. */
975   LOCK_all_lockfiles ();
976   for (hprev=NULL, htmp=all_lockfiles; htmp; hprev=htmp, htmp=htmp->next)
977     if (htmp == h)
978       {
979         if (hprev)
980           hprev->next = htmp->next;
981         else
982           all_lockfiles = htmp->next;
983         h->next = NULL;
984         break;
985       }
986   UNLOCK_all_lockfiles ();
987
988   /* Then destroy the lock. */
989   if (!h->disable)
990     {
991 #ifdef HAVE_DOSISH_SYSTEM
992       dotlock_destroy_w32 (h);
993 #else /* !HAVE_DOSISH_SYSTEM */
994       dotlock_destroy_unix (h);
995 #endif /* HAVE_DOSISH_SYSTEM */
996       xfree (h->lockname);
997     }
998   xfree(h);
999 }
1000
1001
1002 \f
1003 #ifdef HAVE_POSIX_SYSTEM
1004 /* Unix specific code of make_dotlock.  Returns 0 on success and -1 on
1005    error.  */
1006 static int
1007 dotlock_take_unix (dotlock_t h, long timeout)
1008 {
1009   int wtime = 0;
1010   int sumtime = 0;
1011   int pid;
1012   int lastpid = -1;
1013   int ownerchanged;
1014   const char *maybe_dead="";
1015   int same_node;
1016   int saveerrno;
1017
1018  again:
1019   if (h->use_o_excl)
1020     {
1021       /* No hardlink support - use open(O_EXCL).  */
1022       int fd;
1023
1024       do
1025         {
1026           my_set_errno (0);
1027           fd = open (h->lockname, O_WRONLY|O_CREAT|O_EXCL,
1028                      S_IRUSR|S_IRGRP|S_IROTH|S_IWUSR );
1029         }
1030       while (fd == -1 && errno == EINTR);
1031
1032       if (fd == -1 && errno == EEXIST)
1033         ; /* Lock held by another process.  */
1034       else if (fd == -1)
1035         {
1036           saveerrno = errno;
1037           my_error_2 ("lock not made: open(O_EXCL) of '%s' failed: %s\n",
1038                       h->lockname, strerror (saveerrno));
1039           my_set_errno (saveerrno);
1040           return -1;
1041         }
1042       else
1043         {
1044           char pidstr[16];
1045
1046           snprintf (pidstr, sizeof pidstr, "%10d\n", (int)getpid());
1047           if (write (fd, pidstr, 11 ) == 11
1048               && write (fd, h->tname + h->nodename_off,h->nodename_len)
1049               == h->nodename_len
1050               && write (fd, "\n", 1) == 1
1051               && !close (fd))
1052             {
1053               h->locked = 1;
1054               return 0;
1055             }
1056           /* Write error.  */
1057           saveerrno = errno;
1058           my_error_2 ("lock not made: writing to '%s' failed: %s\n",
1059                       h->lockname, strerror (errno));
1060           close (fd);
1061           unlink (h->lockname);
1062           my_set_errno (saveerrno);
1063           return -1;
1064         }
1065     }
1066   else /* Standard method:  Use hardlinks.  */
1067     {
1068       struct stat sb;
1069
1070       /* We ignore the return value of link() because it is unreliable.  */
1071       (void) link (h->tname, h->lockname);
1072
1073       if (stat (h->tname, &sb))
1074         {
1075           saveerrno = errno;
1076           my_error_1 ("lock not made: Oops: stat of tmp file failed: %s\n",
1077                       strerror (errno));
1078           /* In theory this might be a severe error: It is possible
1079              that link succeeded but stat failed due to changed
1080              permissions.  We can't do anything about it, though.  */
1081           my_set_errno (saveerrno);
1082           return -1;
1083         }
1084
1085       if (sb.st_nlink == 2)
1086         {
1087           h->locked = 1;
1088           return 0; /* Okay.  */
1089         }
1090     }
1091
1092   /* Check for stale lock files.  */
1093   if ( (pid = read_lockfile (h, &same_node)) == -1 )
1094     {
1095       if ( errno != ENOENT )
1096         {
1097           saveerrno = errno;
1098           my_info_0 ("cannot read lockfile\n");
1099           my_set_errno (saveerrno);
1100           return -1;
1101         }
1102       my_info_0 ("lockfile disappeared\n");
1103       goto again;
1104     }
1105   else if ( pid == getpid() && same_node )
1106     {
1107       my_info_0 ("Oops: lock already held by us\n");
1108       h->locked = 1;
1109       return 0; /* okay */
1110     }
1111   else if ( same_node && kill (pid, 0) && errno == ESRCH )
1112     {
1113       /* Note: It is unlikley that we get a race here unless a pid is
1114          reused too fast or a new process with the same pid as the one
1115          of the stale file tries to lock right at the same time as we.  */
1116       my_info_1 (_("removing stale lockfile (created by %d)\n"), pid);
1117       unlink (h->lockname);
1118       goto again;
1119     }
1120
1121   if (lastpid == -1)
1122     lastpid = pid;
1123   ownerchanged = (pid != lastpid);
1124
1125   if (timeout)
1126     {
1127       struct timeval tv;
1128
1129       /* Wait until lock has been released.  We use increasing retry
1130          intervals of 50ms, 100ms, 200ms, 400ms, 800ms, 2s, 4s and 8s
1131          but reset it if the lock owner meanwhile changed.  */
1132       if (!wtime || ownerchanged)
1133         wtime = 50;
1134       else if (wtime < 800)
1135         wtime *= 2;
1136       else if (wtime == 800)
1137         wtime = 2000;
1138       else if (wtime < 8000)
1139         wtime *= 2;
1140
1141       if (timeout > 0)
1142         {
1143           if (wtime > timeout)
1144             wtime = timeout;
1145           timeout -= wtime;
1146         }
1147
1148       sumtime += wtime;
1149       if (sumtime >= 1500)
1150         {
1151           sumtime = 0;
1152           my_info_3 (_("waiting for lock (held by %d%s) %s...\n"),
1153                      pid, maybe_dead, maybe_deadlock(h)? _("(deadlock?) "):"");
1154         }
1155
1156
1157       tv.tv_sec = wtime / 1000;
1158       tv.tv_usec = (wtime % 1000) * 1000;
1159       select (0, NULL, NULL, NULL, &tv);
1160       goto again;
1161     }
1162
1163   my_set_errno (EACCES);
1164   return -1;
1165 }
1166 #endif /*HAVE_POSIX_SYSTEM*/
1167
1168
1169 #ifdef HAVE_DOSISH_SYSTEM
1170 /* Windows specific code of make_dotlock.  Returns 0 on success and -1 on
1171    error.  */
1172 static int
1173 dotlock_take_w32 (dotlock_t h, long timeout)
1174 {
1175   int wtime = 0;
1176   int w32err;
1177   OVERLAPPED ovl;
1178
1179  again:
1180   /* Lock one byte at offset 0.  The offset is given by OVL.  */
1181   memset (&ovl, 0, sizeof ovl);
1182   if (LockFileEx (h->lockhd, (LOCKFILE_EXCLUSIVE_LOCK
1183                               | LOCKFILE_FAIL_IMMEDIATELY), 0, 1, 0, &ovl))
1184     {
1185       h->locked = 1;
1186       return 0; /* okay */
1187     }
1188
1189   w32err = GetLastError ();
1190   if (w32err != ERROR_LOCK_VIOLATION)
1191     {
1192       my_error_2 (_("lock '%s' not made: %s\n"),
1193                   h->lockname, w32_strerror (w32err));
1194       my_set_errno (map_w32_to_errno (w32err));
1195       return -1;
1196     }
1197
1198   if (timeout)
1199     {
1200       /* Wait until lock has been released.  We use retry intervals of
1201          50ms, 100ms, 200ms, 400ms, 800ms, 2s, 4s and 8s.  */
1202       if (!wtime)
1203         wtime = 50;
1204       else if (wtime < 800)
1205         wtime *= 2;
1206       else if (wtime == 800)
1207         wtime = 2000;
1208       else if (wtime < 8000)
1209         wtime *= 2;
1210
1211       if (timeout > 0)
1212         {
1213           if (wtime > timeout)
1214             wtime = timeout;
1215           timeout -= wtime;
1216         }
1217
1218       if (wtime >= 800)
1219         my_info_1 (_("waiting for lock %s...\n"), h->lockname);
1220
1221       Sleep (wtime);
1222       goto again;
1223     }
1224
1225   my_set_errno (EACCES);
1226   return -1;
1227 }
1228 #endif /*HAVE_DOSISH_SYSTEM*/
1229
1230
1231 /* Take a lock on H.  A value of 0 for TIMEOUT returns immediately if
1232    the lock can't be taked, -1 waits forever (hopefully not), other
1233    values wait for TIMEOUT milliseconds.  Returns: 0 on success  */
1234 int
1235 dotlock_take (dotlock_t h, long timeout)
1236 {
1237   int ret;
1238
1239   if ( h->disable )
1240     return 0; /* Locks are completely disabled.  Return success. */
1241
1242   if ( h->locked )
1243     {
1244       my_debug_1 ("Oops, '%s' is already locked\n", h->lockname);
1245       return 0;
1246     }
1247
1248 #ifdef HAVE_DOSISH_SYSTEM
1249   ret = dotlock_take_w32 (h, timeout);
1250 #else /*!HAVE_DOSISH_SYSTEM*/
1251   ret = dotlock_take_unix (h, timeout);
1252 #endif /*!HAVE_DOSISH_SYSTEM*/
1253
1254   return ret;
1255 }
1256
1257
1258 \f
1259 #ifdef HAVE_POSIX_SYSTEM
1260 /* Unix specific code of release_dotlock.  */
1261 static int
1262 dotlock_release_unix (dotlock_t h)
1263 {
1264   int pid, same_node;
1265   int saveerrno;
1266
1267   pid = read_lockfile (h, &same_node);
1268   if ( pid == -1 )
1269     {
1270       saveerrno = errno;
1271       my_error_0 ("release_dotlock: lockfile error\n");
1272       my_set_errno (saveerrno);
1273       return -1;
1274     }
1275   if ( pid != getpid() || !same_node )
1276     {
1277       my_error_1 ("release_dotlock: not our lock (pid=%d)\n", pid);
1278       my_set_errno (EACCES);
1279       return -1;
1280     }
1281
1282   if ( unlink( h->lockname ) )
1283     {
1284       saveerrno = errno;
1285       my_error_1 ("release_dotlock: error removing lockfile '%s'\n",
1286                   h->lockname);
1287       my_set_errno (saveerrno);
1288       return -1;
1289     }
1290   /* Fixme: As an extra check we could check whether the link count is
1291      now really at 1. */
1292   return 0;
1293 }
1294 #endif /*HAVE_POSIX_SYSTEM */
1295
1296
1297 #ifdef HAVE_DOSISH_SYSTEM
1298 /* Windows specific code of release_dotlock.  */
1299 static int
1300 dotlock_release_w32 (dotlock_t h)
1301 {
1302   OVERLAPPED ovl;
1303
1304   memset (&ovl, 0, sizeof ovl);
1305   if (!UnlockFileEx (h->lockhd, 0, 1, 0, &ovl))
1306     {
1307       int saveerrno = map_w32_to_errno (GetLastError ());
1308       my_error_2 ("release_dotlock: error removing lockfile '%s': %s\n",
1309                   h->lockname, w32_strerror (-1));
1310       my_set_errno (saveerrno);
1311       return -1;
1312     }
1313
1314   return 0;
1315 }
1316 #endif /*HAVE_DOSISH_SYSTEM */
1317
1318
1319 /* Release a lock.  Returns 0 on success.  */
1320 int
1321 dotlock_release (dotlock_t h)
1322 {
1323   int ret;
1324
1325   /* To avoid atexit race conditions we first check whether there are
1326      any locks left.  It might happen that another atexit handler
1327      tries to release the lock while the atexit handler of this module
1328      already ran and thus H is undefined.  */
1329   LOCK_all_lockfiles ();
1330   ret = !all_lockfiles;
1331   UNLOCK_all_lockfiles ();
1332   if (ret)
1333     return 0;
1334
1335   if ( h->disable )
1336     return 0;
1337
1338   if ( !h->locked )
1339     {
1340       my_debug_1 ("Oops, '%s' is not locked\n", h->lockname);
1341       return 0;
1342     }
1343
1344 #ifdef HAVE_DOSISH_SYSTEM
1345   ret = dotlock_release_w32 (h);
1346 #else
1347   ret = dotlock_release_unix (h);
1348 #endif
1349
1350   if (!ret)
1351     h->locked = 0;
1352   return ret;
1353 }
1354
1355
1356 \f
1357 /* Remove all lockfiles.  This is called by the atexit handler
1358    installed by this module but may also be called by other
1359    termination handlers.  */
1360 void
1361 dotlock_remove_lockfiles (void)
1362 {
1363   dotlock_t h, h2;
1364
1365   /* First set the lockfiles list to NULL so that for example
1366      dotlock_release is aware that this function is currently
1367      running.  */
1368   LOCK_all_lockfiles ();
1369   h = all_lockfiles;
1370   all_lockfiles = NULL;
1371   UNLOCK_all_lockfiles ();
1372
1373   while ( h )
1374     {
1375       h2 = h->next;
1376       dotlock_destroy (h);
1377       h = h2;
1378     }
1379 }