From aae79dfaac44dcb0d5d4ea8fa6de5a735dd39060 Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn@redhat.com>
Date: Fri, 8 Mar 2013 14:26:42 +0100
Subject: [PATCH 1/2] Reuse sss_open_cloexec at other places in code.

Functions open_cloexec and openat_cloexec were renamed with prefix
"sss_" and moved to separete file. Replacing duplicated code of
function sss_open_cloexec everywhere in the source code.

https://fedorahosted.org/sssd/ticket/1794
---
 Makefile.am                    |  3 +-
 src/sss_client/nss_mc_common.c | 19 +--------
 src/tools/files.c              | 70 ++------------------------------
 src/util/compact.c             | 90 ++++++++++++++++++++++++++++++++++++++++++
 src/util/util.h                |  3 ++
 5 files changed, 101 insertions(+), 84 deletions(-)
 create mode 100644 src/util/compact.c

diff --git a/Makefile.am b/Makefile.am
index c66e25525c2a652681eb8ff2cd607d368d59bc81..7ed46aced31ab93b1d56450902faa11c648c7010 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -527,7 +527,8 @@ libsss_util_la_SOURCES = \
     src/util/sss_selinux.c \
     src/util/domain_info_utils.c \
     src/util/util_lock.c \
-    src/util/util_errors.c
+    src/util/util_errors.c \
+    src/util/compact.c
 libsss_util_la_LIBADD = \
     $(SSSD_LIBS) \
     $(UNICODE_LIBS) \
diff --git a/src/sss_client/nss_mc_common.c b/src/sss_client/nss_mc_common.c
index 78490bef0edc99efbd1b953c35183921d5b02b64..66442b7174c38fa4e486b979e8067b1b4dfe448d 100644
--- a/src/sss_client/nss_mc_common.c
+++ b/src/sss_client/nss_mc_common.c
@@ -31,6 +31,7 @@
 #include <string.h>
 #include <stdlib.h>
 #include "nss_mc.h"
+#include "util/util.h"
 
 /* FIXME: hook up to library destructor to avoid leaks */
 /* FIXME: temporarily open passwd file on our own, later we will probably
@@ -100,12 +101,6 @@ errno_t sss_nss_check_header(struct sss_cli_mc_ctx *ctx)
     return 0;
 }
 
-#ifdef O_CLOEXEC
-#define SSS_MC_OPEN_FLAGS O_RDONLY|O_CLOEXEC
-#else
-#define SSS_MC_OPEN_FLAGS O_RDONLY
-#endif
-
 errno_t sss_nss_mc_get_ctx(const char *name, struct sss_cli_mc_ctx *ctx)
 {
     struct stat fdstat;
@@ -129,19 +124,9 @@ errno_t sss_nss_mc_get_ctx(const char *name, struct sss_cli_mc_ctx *ctx)
         goto done;
     }
 
-    ctx->fd = open(file, SSS_MC_OPEN_FLAGS);
+    ctx->fd = sss_open_cloexec(file, O_RDONLY, &ret);
     if (ctx->fd == -1) {
-        ret = EIO;
         goto done;
-#ifndef O_CLOEXEC
-    } else {
-        int v;
-
-        v = fcntl(ctx->fd, F_GETFD, 0);
-        /* we ignore an error, it's not fatal and there is nothing we
-         * can do about it anyways */
-        (void)fcntl(ctx->fd, F_SETFD, v | FD_CLOEXEC);
-#endif
     }
 
     ret = fstat(ctx->fd, &fdstat);
diff --git a/src/tools/files.c b/src/tools/files.c
index 572617296b78e0443fdacf12443d7a9b76ebdd86..10fd6fe4396b3826a3ff65b8d84d3e0a1baddf5b 100644
--- a/src/tools/files.c
+++ b/src/tools/files.c
@@ -75,68 +75,6 @@ struct copy_ctx {
     gid_t       gid;
 };
 
-static int open_cloexec(const char *pathname, int flags, int *ret)
-{
-    int fd;
-    int oflags;
-
-    oflags = flags;
-#ifdef O_CLOEXEC
-    oflags |= O_CLOEXEC;
-#endif
-
-    errno = 0;
-    fd = open(pathname, oflags);
-    if (fd == -1) {
-        if (ret) {
-            *ret = errno;
-        }
-        return -1;
-    }
-
-#ifndef O_CLOEXEC
-    int v;
-
-    v = fcntl(fd, F_GETFD, 0);
-    /* we ignore an error, it's not fatal and there is nothing we
-     * can do about it anyways */
-    (void)fcntl(fd, F_SETFD, v | FD_CLOEXEC);
-#endif
-
-    return fd;
-}
-
-static int openat_cloexec(int dir_fd, const char *pathname, int flags, int *ret)
-{
-    int fd;
-    int oflags;
-
-    oflags = flags;
-#ifdef O_CLOEXEC
-    oflags |= O_CLOEXEC;
-#endif
-
-    errno = 0;
-    fd = openat(dir_fd, pathname, oflags);
-    if (fd == -1) {
-        if (ret) {
-            *ret = errno;
-        }
-        return -1;
-    }
-
-#ifndef O_CLOEXEC
-    int v;
-
-    v = fcntl(fd, F_GETFD, 0);
-    /* we ignore an error, it's not fatal and there is nothing we
-     * can do about it anyways */
-    (void)fcntl(fd, F_SETFD, v | FD_CLOEXEC);
-#endif
-
-    return fd;
-}
-
 static int sss_timeat_set(int dir_fd, const char *path,
                           const struct stat *statp,
                           int flags)
@@ -232,7 +170,7 @@ static int remove_tree_with_ctx(TALLOC_CTX *mem_ctx,
     int ret, err;
     int dir_fd;
 
-    dir_fd = openat_cloexec(parent_fd, dir_name,
+    dir_fd = sss_openat_cloexec(parent_fd, dir_name,
                             O_RDONLY | O_DIRECTORY | O_NOFOLLOW, &ret);
     if (dir_fd == -1) {
         ret = errno;
@@ -607,7 +545,7 @@ copy_entry(struct copy_ctx *cctx,
      * us against FIFOs and perhaps side-effects of the open() of a
      * device file if there ever was one here, and doesn't matter
      * for regular files or directories. */
-    ifd = openat_cloexec(src_dir_fd, ent_name,
+    ifd = sss_openat_cloexec(src_dir_fd, ent_name,
                          O_RDONLY | O_NOFOLLOW | O_NONBLOCK, &ret);
     if (ifd == -1 && ret != ELOOP) {
         /* openat error */
@@ -721,7 +659,7 @@ copy_dir(struct copy_ctx *cctx,
         goto done;
     }
 
-    dest_dir_fd = openat_cloexec(dest_parent_fd, dest_dir_name,
+    dest_dir_fd = sss_openat_cloexec(dest_parent_fd, dest_dir_name,
                                  O_RDONLY | O_DIRECTORY | O_NOFOLLOW, &ret);
     if (dest_dir_fd == -1) {
         ret = errno;
@@ -807,7 +745,7 @@ int copy_tree(const char *src_root, const char *dst_root,
     int fd = -1;
     struct stat s_src;
 
-    fd = open_cloexec(src_root, O_RDONLY | O_DIRECTORY, &ret);
+    fd = sss_open_cloexec(src_root, O_RDONLY | O_DIRECTORY, &ret);
     if (fd == -1) {
         goto fail;
     }
diff --git a/src/util/compact.c b/src/util/compact.c
new file mode 100644
index 0000000000000000000000000000000000000000..e07a18c56b97b41409fed35066a7d6ab70cd753d
--- /dev/null
+++ b/src/util/compact.c
@@ -0,0 +1,90 @@
+/*
+    SSSD
+
+    compact.c
+
+    Authors:
+        Lukas Slebodnik <lslebodn@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 "util/util.h"
+
+int sss_open_cloexec(const char *pathname, int flags, int *ret)
+{
+    int fd;
+    int oflags;
+
+    oflags = flags;
+#ifdef O_CLOEXEC
+    oflags |= O_CLOEXEC;
+#endif
+
+    errno = 0;
+    fd = open(pathname, oflags);
+    if (fd == -1) {
+        if (ret) {
+            *ret = errno;
+        }
+        return -1;
+    }
+
+#ifndef O_CLOEXEC
+    int v;
+
+    v = fcntl(fd, F_GETFD, 0);
+    /* we ignore an error, it's not fatal and there is nothing we
+     * can do about it anyways */
+    (void)fcntl(fd, F_SETFD, v | FD_CLOEXEC);
+#endif
+
+    return fd;
+}
+
+int sss_openat_cloexec(int dir_fd, const char *pathname, int flags, int *ret)
+{
+    int fd;
+    int oflags;
+
+    oflags = flags;
+#ifdef O_CLOEXEC
+    oflags |= O_CLOEXEC;
+#endif
+
+    errno = 0;
+    fd = openat(dir_fd, pathname, oflags);
+    if (fd == -1) {
+        if (ret) {
+            *ret = errno;
+        }
+        return -1;
+    }
+
+#ifndef O_CLOEXEC
+    int v;
+
+    v = fcntl(fd, F_GETFD, 0);
+    /* we ignore an error, it's not fatal and there is nothing we
+     * can do about it anyways */
+    (void)fcntl(fd, F_SETFD, v | FD_CLOEXEC);
+#endif
+
+    return fd;
+}
diff --git a/src/util/util.h b/src/util/util.h
index 8afb3bc964dfc7ea5debf8127b7c6bac08d11f42..2adc8cb4180ae802afee63d084c3d1d67f273862 100644
--- a/src/util/util.h
+++ b/src/util/util.h
@@ -584,6 +584,9 @@ errno_t sssd_domain_init(TALLOC_CTX *mem_ctx,
 /* from util_lock.c */
 errno_t sss_br_lock_file(int fd, size_t start, size_t len,
                          int num_tries, useconds_t wait);
+/* from compact.c */
+int sss_open_cloexec(const char *pathname, int flags, int *ret);
+int sss_openat_cloexec(int dir_fd, const char *pathname, int flags, int *ret);
 
 /* Endianness-compatibility for systems running older versions of glibc */
 
-- 
1.8.1.4

