imapext-2007

view src/osdep/unix/flocklnx.c @ 0:ada5e610ab86

imap-2007e
author yuuji@gentei.org
date Mon, 14 Sep 2009 15:17:45 +0900
parents
children
line source
1 /* ========================================================================
2 * Copyright 1988-2006 University of Washington
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 *
11 * ========================================================================
12 */
14 /*
15 * Program: Safe File Lock for Linux
16 *
17 * Author: Mark Crispin
18 * Networks and Distributed Computing
19 * Computing & Communications
20 * University of Washington
21 * Administration Building, AG-44
22 * Seattle, WA 98195
23 * Internet: MRC@CAC.Washington.EDU
24 *
25 * Date: 20 April 2005
26 * Last Edited: 30 August 2006
27 */
29 #undef flock
31 #include <sys/vfs.h>
32 #ifndef NFS_SUPER_MAGIC
33 #define NFS_SUPER_MAGIC 0x6969
34 #endif
36 int safe_flock (int fd,int op)
37 {
38 struct statfs sfbuf;
39 char tmp[MAILTMPLEN];
40 int e;
41 int logged = 0;
42 /* Check for NFS because Linux 2.6 broke flock() on NFS. Instead of being
43 * a no-op, flock() on NFS now returns ENOLCK. Read
44 * https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=123415
45 * for the gruesome details.
46 */
47 /* check filesystem type */
48 while ((e = fstatfs (fd,&sfbuf)) && (errno == EINTR));
49 if (!e) switch (sfbuf.f_type) {
50 case NFS_SUPER_MAGIC: /* always a fast no-op on NFS */
51 break;
52 default: /* allow on other filesystem types */
53 /* do the lock */
54 while (flock (fd,op)) switch (errno) {
55 case EINTR: /* interrupt */
56 break;
57 case ENOLCK: /* lock table is full */
58 sprintf (tmp,"File locking failure: %s",strerror (errno));
59 mm_log (tmp,WARN); /* give the user a warning of what happened */
60 if (!logged++) syslog (LOG_ERR,tmp);
61 /* return failure if non-blocking lock */
62 if (op & LOCK_NB) return -1;
63 sleep (5); /* slow down in case it loops */
64 break;
65 case EWOULDBLOCK: /* file is locked, LOCK_NB should be set */
66 if (op & LOCK_NB) return -1;
67 case EBADF: /* not valid open file descriptor */
68 case EINVAL: /* invalid operator */
69 default: /* other error code? */
70 sprintf (tmp,"Unexpected file locking failure: %s",strerror (errno));
71 fatal (tmp);
72 }
73 break;
74 }
75 return 0; /* success */
76 }

UW-IMAP'd extensions by yuuji