summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMichal Zidek <mzidek@redhat.com>2012-10-31 11:05:31 +0100
committerJakub Hrozek <jhrozek@redhat.com>2012-11-06 12:29:28 +0100
commit0a55f903a1da319338fdcf147efa01ed22f9710d (patch)
tree40177e5faa17c4cbcb6382cc6607e74d119b5a11 /src
parent69f6f2ed116d1c987851bfcc410cf2bdd1b0cc97 (diff)
downloadsssd-0a55f903a1da319338fdcf147efa01ed22f9710d.tar.gz
sssd-0a55f903a1da319338fdcf147efa01ed22f9710d.tar.xz
sssd-0a55f903a1da319338fdcf147efa01ed22f9710d.zip
util: Added new file util_lock.c
Diffstat (limited to 'src')
-rw-r--r--src/util/util.h4
-rw-r--r--src/util/util_lock.c83
2 files changed, 87 insertions, 0 deletions
diff --git a/src/util/util.h b/src/util/util.h
index de9e6b89a..d9315aefe 100644
--- a/src/util/util.h
+++ b/src/util/util.h
@@ -559,6 +559,10 @@ struct sss_domain_info *new_subdomain(TALLOC_CTX *mem_ctx,
struct sss_domain_info *copy_subdomain(TALLOC_CTX *mem_ctx,
struct sss_domain_info *subdomain);
+/* from util_lock.c */
+errno_t sss_br_lock_file(int fd, size_t start, size_t len,
+ int retries, useconds_t wait);
+
/* Endianness-compatibility for systems running older versions of glibc */
#ifndef le32toh
diff --git a/src/util/util_lock.c b/src/util/util_lock.c
new file mode 100644
index 000000000..c2d7fac77
--- /dev/null
+++ b/src/util/util_lock.c
@@ -0,0 +1,83 @@
+/*
+ SSSD
+
+ util_lock.c
+
+ Authors:
+ Michal Zidek <mzidek@redhat.com>
+
+ Copyright (C) 2012 Red Hat
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include "util/util.h"
+
+errno_t sss_br_lock_file(int fd, size_t start, size_t len,
+ int retries, useconds_t wait)
+{
+ int ret;
+ struct flock lock;
+ int retries_left;
+
+ lock.l_type = F_WRLCK;
+ lock.l_whence = SEEK_SET;
+ lock.l_start = start;
+ lock.l_len = len;
+ lock.l_pid = 0;
+
+ for (retries_left = retries; retries_left > 0; retries_left--) {
+ ret = fcntl(fd, F_SETLK, &lock);
+ if (ret == -1) {
+ ret = errno;
+ if (ret == EACCES || ret == EAGAIN || ret == EINTR) {
+ DEBUG(SSSDBG_TRACE_FUNC,
+ ("Failed to lock file. Retries left: %d\n",
+ retries_left - 1));
+
+ if ((ret == EACCES || ret == EAGAIN) && (retries_left <= 1)) {
+ /* File is locked by someone else. Return EACCESS
+ * if this is the last try. */
+ return EACCES;
+ }
+
+ if (retries_left - 1 > 0) {
+ ret = usleep(wait);
+ if (ret == -1) {
+ DEBUG(SSSDBG_MINOR_FAILURE,
+ ("usleep() failed -> ignoring\n"));
+ }
+ }
+ } else {
+ /* Error occurred */
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ ("Unable to lock file.\n"));
+ return ret;
+ }
+ } else if (ret == 0) {
+ /* File successfuly locked */
+ break;
+ }
+ }
+ if (retries_left == 0) {
+ DEBUG(SSSDBG_CRIT_FAILURE, ("Unable to lock file.\n"));
+ return ret;
+ }
+
+ return EOK;
+}