Line data Source code
1 : /*
2 : SSSD
3 :
4 : util_lock.c
5 :
6 : Authors:
7 : Michal Zidek <mzidek@redhat.com>
8 :
9 : Copyright (C) 2012 Red Hat
10 :
11 : This program is free software; you can redistribute it and/or modify
12 : it under the terms of the GNU General Public License as published by
13 : the Free Software Foundation; either version 3 of the License, or
14 : (at your option) any later version.
15 :
16 : This program is distributed in the hope that it will be useful,
17 : but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : GNU General Public License for more details.
20 :
21 : You should have received a copy of the GNU General Public License
22 : along with this program. If not, see <http://www.gnu.org/licenses/>.
23 : */
24 :
25 : #include <unistd.h>
26 : #include <fcntl.h>
27 : #include <errno.h>
28 :
29 : #include "util/util.h"
30 :
31 0 : errno_t sss_br_lock_file(int fd, size_t start, size_t len,
32 : int num_tries, useconds_t wait)
33 : {
34 : int ret;
35 : struct flock lock;
36 : int retries_left;
37 :
38 0 : if (num_tries <= 0) {
39 0 : return EINVAL;
40 : }
41 :
42 0 : lock.l_type = F_WRLCK;
43 0 : lock.l_whence = SEEK_SET;
44 0 : lock.l_start = start;
45 0 : lock.l_len = len;
46 0 : lock.l_pid = 0;
47 :
48 0 : for (retries_left = num_tries; retries_left > 0; retries_left--) {
49 0 : ret = fcntl(fd, F_SETLK, &lock);
50 0 : if (ret == -1) {
51 0 : ret = errno;
52 0 : if (ret == EACCES || ret == EAGAIN || ret == EINTR) {
53 0 : DEBUG(SSSDBG_TRACE_FUNC,
54 : "Failed to lock file. Retries left: %d\n",
55 : retries_left - 1);
56 :
57 0 : if ((ret == EACCES || ret == EAGAIN) && (retries_left <= 1)) {
58 : /* File is locked by someone else. Return EACCESS
59 : * if this is the last try. */
60 0 : return EACCES;
61 : }
62 :
63 0 : if (retries_left - 1 > 0) {
64 0 : ret = usleep(wait);
65 0 : if (ret == -1) {
66 0 : DEBUG(SSSDBG_MINOR_FAILURE,
67 : "usleep() failed -> ignoring\n");
68 : }
69 : }
70 : } else {
71 : /* Error occurred */
72 0 : DEBUG(SSSDBG_CRIT_FAILURE,
73 : "Unable to lock file.\n");
74 0 : return ret;
75 : }
76 0 : } else if (ret == 0) {
77 : /* File successfuly locked */
78 0 : break;
79 : }
80 : }
81 0 : if (retries_left == 0) {
82 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Unable to lock file.\n");
83 0 : return ret;
84 : }
85 :
86 0 : return EOK;
87 : }
|