autofs-5.1.9 - move open close on exec functions to autofs library

From: Ian Kent <raven@themaw.net>

Move the open close on exec functions to the autofs library.

Signed-off-by: Ian Kent <raven@themaw.net>
---
 CHANGELOG           |    1 
 daemon/spawn.c      |  208 -------------------------------------------
 include/automount.h |    2 
 include/misc.h      |   32 +++++++
 lib/Makefile        |    4 -
 lib/misc.c          |  244 +++++++++++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 280 insertions(+), 211 deletions(-)
 create mode 100644 include/misc.h
 create mode 100644 lib/misc.c

diff --git a/CHANGELOG b/CHANGELOG
index 883e51390..aa9fa182a 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -59,6 +59,7 @@
 - fix sublink option check length in update_with_defaults().
 - dont assume non null tree node in tree_free().
 - add missing cache_unlock() in umount_subtree_mounts().
+- move open close on exec functions to autofs library.
 
 02/11/2023 autofs-5.1.9
 - fix kernel mount status notification.
diff --git a/daemon/spawn.c b/daemon/spawn.c
index 452a18d0c..3d185e9d3 100644
--- a/daemon/spawn.c
+++ b/daemon/spawn.c
@@ -31,7 +31,6 @@
 #include "automount.h"
 
 static pthread_mutex_t spawn_mutex = PTHREAD_MUTEX_INITIALIZER;
-static pthread_mutex_t open_mutex = PTHREAD_MUTEX_INITIALIZER;
 
 #define SPAWN_OPT_NONE		0x0000
 #define SPAWN_OPT_LOCK		0x0001
@@ -39,213 +38,6 @@ static pthread_mutex_t open_mutex = PTHREAD_MUTEX_INITIALIZER;
 
 #define MTAB_LOCK_RETRIES	3
 
-void dump_core(void)
-{
-	sigset_t segv;
-
-	sigemptyset(&segv);
-	sigaddset(&segv, SIGSEGV);
-	pthread_sigmask(SIG_UNBLOCK, &segv, NULL);
-
-	raise(SIGSEGV);
-}
-
-void open_mutex_lock(void)
-{
-	int _o_lock = pthread_mutex_lock(&open_mutex);
-	if (_o_lock)
-		fatal(_o_lock);
-}
-
-void open_mutex_unlock(void)
-{
-	int _o_unlock = pthread_mutex_unlock(&open_mutex);
-	if (_o_unlock)
-		fatal(_o_unlock);
-}
-
-/*
- * Use CLOEXEC flag for open(), pipe(), fopen() (read-only case) and
- * socket() if possible.
- */
-static int cloexec_works = 0;
-
-static void check_cloexec(int fd)
-{
-	if (cloexec_works == 0) {
-		int fl = fcntl(fd, F_GETFD);
-		if (fl != -1)
-			cloexec_works = (fl & FD_CLOEXEC) ? 1 : -1;
-	}
-	if (cloexec_works > 0)
-		return;
-	fcntl(fd, F_SETFD, FD_CLOEXEC);
-	return;
-}
-
-int open_fd(const char *path, int flags)
-{
-	int fd;
-
-	open_mutex_lock();
-#if defined(O_CLOEXEC) && defined(SOCK_CLOEXEC)
-	if (cloexec_works != -1)
-		flags |= O_CLOEXEC;
-#endif
-	fd = open(path, flags);
-	if (fd == -1) {
-		char buf[MAX_ERR_BUF];
-		char *estr;
-
-		open_mutex_unlock();
-		estr = strerror_r(errno, buf, sizeof(buf));
-		logerr("failed to open file: %s", estr);
-		return -1;
-	}
-	check_cloexec(fd);
-	open_mutex_unlock();
-	return fd;
-}
-
-int open_fd_mode(const char *path, int flags, int mode)
-{
-	int fd;
-
-	open_mutex_lock();
-#if defined(O_CLOEXEC) && defined(SOCK_CLOEXEC)
-	if (cloexec_works != -1)
-		flags |= O_CLOEXEC;
-#endif
-	fd = open(path, flags, mode);
-	if (fd == -1) {
-		char buf[MAX_ERR_BUF];
-		char *estr;
-
-		open_mutex_unlock();
-		estr = strerror_r(errno, buf, sizeof(buf));
-		logerr("failed to open file: %s", estr);
-		return -1;
-	}
-	check_cloexec(fd);
-	open_mutex_unlock();
-	return fd;
-}
-
-int open_pipe(int pipefd[2])
-{
-	char buf[MAX_ERR_BUF];
-	char *estr;
-	int ret;
-
-	open_mutex_lock();
-#if defined(O_CLOEXEC) && defined(SOCK_CLOEXEC) && defined(HAVE_PIPE2)
-	if (cloexec_works != -1) {
-		ret = pipe2(pipefd, O_CLOEXEC);
-		if (ret != -1)
-			goto done;
-		if (errno != EINVAL)
-			goto err;
-	}
-#endif
-	ret = pipe(pipefd);
-	if (ret == -1)
-		goto err;
-	check_cloexec(pipefd[0]);
-	check_cloexec(pipefd[1]);
-done:
-	open_mutex_unlock();
-	return 0;
-err:
-	open_mutex_unlock();
-	estr = strerror_r(errno, buf, sizeof(buf));
-	logerr("failed to open pipe: %s", estr);
-	return -1;
-}
-
-int open_sock(int domain, int type, int protocol)
-{
-	int fd;
-
-	open_mutex_lock();
-#ifdef SOCK_CLOEXEC
-	if (cloexec_works != -1)
-		type |= SOCK_CLOEXEC;
-#endif
-	fd = socket(domain, type, protocol);
-	if (fd == -1) {
-		char buf[MAX_ERR_BUF];
-		char *estr;
-
-		open_mutex_unlock();
-		estr = strerror_r(errno, buf, sizeof(buf));
-		logerr("failed to open socket: %s", estr);
-		return -1;
-	}
-	check_cloexec(fd);
-	open_mutex_unlock();
-	return fd;
-}
-
-FILE *open_fopen_r(const char *path)
-{
-	FILE *f;
-
-	open_mutex_lock();
-#if defined(O_CLOEXEC) && defined(SOCK_CLOEXEC)
-	if (cloexec_works != -1) {
-		f = fopen(path, "re");
-		if (f != NULL) {
-			check_cloexec(fileno(f));
-			open_mutex_unlock();
-			return f;
-		}
-	}
-#endif
-	f = fopen(path, "r");
-	if (f == NULL) {
-		char buf[MAX_ERR_BUF];
-		char *estr;
-
-		open_mutex_unlock();
-		estr = strerror_r(errno, buf, sizeof(buf));
-		logerr("failed to open file: %s", estr);
-		return NULL;
-	}
-	check_cloexec(fileno(f));
-	open_mutex_unlock();
-	return f;
-}
-
-FILE *open_setmntent_r(const char *table)
-{
-	FILE *tab;
-
-	open_mutex_lock();
-#if defined(O_CLOEXEC) && defined(SOCK_CLOEXEC)
-	if (cloexec_works != -1) {
-		tab = setmntent(table, "re");
-		if (tab != NULL) {
-			check_cloexec(fileno(tab));
-			open_mutex_unlock();
-			return tab;
-		}
-	}
-#endif
-	tab = fopen(table, "r");
-	if (tab == NULL) {
-		char buf[MAX_ERR_BUF];
-		char *estr;
-
-		open_mutex_unlock();
-		estr = strerror_r(errno, buf, sizeof(buf));
-		logerr("failed to open mount table: %s", estr);
-		return NULL;
-	}
-	check_cloexec(fileno(tab));
-	open_mutex_unlock();
-	return tab;
-}
-
 /*
  * Used by subprocesses which exec to avoid carrying over the main
  * daemon's signalling environment
diff --git a/include/automount.h b/include/automount.h
index fd7219d52..7b7ee41b3 100644
--- a/include/automount.h
+++ b/include/automount.h
@@ -37,6 +37,7 @@
 #include "parse_subs.h"
 #include "dev-ioctl-lib.h"
 #include "parse_amd.h"
+#include "misc.h"
 
 #ifdef WITH_DMALLOC
 #include <dmalloc.h>
@@ -237,7 +238,6 @@ int free_argv(int argc, const char **argv);
 struct pending_args;
 void set_thread_mount_request_log_id(struct pending_args *mt);
 
-void dump_core(void);
 int aquire_lock(void);
 void release_lock(void);
 int spawnl(unsigned logopt, const char *prog, ...);
diff --git a/include/misc.h b/include/misc.h
new file mode 100644
index 000000000..d02058f00
--- /dev/null
+++ b/include/misc.h
@@ -0,0 +1,32 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *  Copyright 2023 Ian Kent <raven@themaw.net>
+ *  Copyright 2023 Red Hat, Inc.
+ *  All rights reserved.
+ *
+ *  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, Inc., 675 Mass Ave, Cambridge MA 02139,
+ *  USA; either version 2 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.
+ *
+ * ----------------------------------------------------------------------- */
+#ifndef MISC_H
+#define MISC_H
+#include <stdio.h>
+
+void dump_core(void);
+void open_mutex_lock(void);
+void open_mutex_unlock(void);
+int open_fd(const char *path, int flags);
+int open_fd_mode(const char *path, int flags, int mode);
+int open_pipe(int pipefd[2]);
+int open_sock(int domain, int type, int protocol);
+FILE *open_fopen_r(const char *path);
+FILE *open_setmntent_r(const char *table);
+#endif
diff --git a/lib/Makefile b/lib/Makefile
index d18c67b58..8ee7c012f 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -7,10 +7,10 @@ include ../Makefile.rules
 
 SRCS = cache.c cat_path.c rpc_subs.c mounts.c log.c nsswitch.c \
 	nss_tok.c nss_parse.tab.c args.c alarm.c macros.c defaults.c \
-	parse_subs.c dev-ioctl-lib.c
+	parse_subs.c dev-ioctl-lib.c misc.c
 OBJS = cache.o cat_path.o rpc_subs.o mounts.o log.o nsswitch.o \
 	nss_tok.o nss_parse.tab.o args.o alarm.o macros.o defaults.o \
-	parse_subs.o dev-ioctl-lib.o
+	parse_subs.o dev-ioctl-lib.o misc.o
 
 YACCSRC = nss_tok.c nss_parse.tab.c nss_parse.tab.h
 
diff --git a/lib/misc.c b/lib/misc.c
new file mode 100644
index 000000000..453d713b6
--- /dev/null
+++ b/lib/misc.c
@@ -0,0 +1,244 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *  Copyright 2023 Ian Kent <raven@themaw.net>
+ *  Copyright 2023 Red Hat, Inc.
+ *  All rights reserved.
+ *
+ *  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, Inc., 675 Mass Ave, Cambridge MA 02139,
+ *  USA; either version 2 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.
+ *
+ * ----------------------------------------------------------------------- */
+#include <sys/socket.h>
+#include <signal.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <limits.h>
+#include <string.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <mntent.h>
+
+#include "log.h"
+#include "misc.h"
+
+#define MAX_ERR_BUF	128
+
+static pthread_mutex_t open_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+void dump_core(void)
+{
+	sigset_t segv;
+
+	sigemptyset(&segv);
+	sigaddset(&segv, SIGSEGV);
+	pthread_sigmask(SIG_UNBLOCK, &segv, NULL);
+
+	raise(SIGSEGV);
+}
+
+void open_mutex_lock(void)
+{
+	int _o_lock = pthread_mutex_lock(&open_mutex);
+	if (_o_lock)
+		fatal(_o_lock);
+}
+
+void open_mutex_unlock(void)
+{
+	int _o_unlock = pthread_mutex_unlock(&open_mutex);
+	if (_o_unlock)
+		fatal(_o_unlock);
+}
+
+/*
+ * Use CLOEXEC flag for open(), pipe(), fopen() (read-only case) and
+ * socket() if possible.
+ */
+static int cloexec_works = 0;
+
+static void check_cloexec(int fd)
+{
+	if (cloexec_works == 0) {
+		int fl = fcntl(fd, F_GETFD);
+		if (fl != -1)
+			cloexec_works = (fl & FD_CLOEXEC) ? 1 : -1;
+	}
+	if (cloexec_works > 0)
+		return;
+	fcntl(fd, F_SETFD, FD_CLOEXEC);
+	return;
+}
+
+int open_fd(const char *path, int flags)
+{
+	int fd;
+
+	open_mutex_lock();
+#if defined(O_CLOEXEC) && defined(SOCK_CLOEXEC)
+	if (cloexec_works != -1)
+		flags |= O_CLOEXEC;
+#endif
+	fd = open(path, flags);
+	if (fd == -1) {
+		char buf[MAX_ERR_BUF];
+		char *estr;
+
+		open_mutex_unlock();
+		estr = strerror_r(errno, buf, sizeof(buf));
+		logerr("failed to open file: %s", estr);
+		return -1;
+	}
+	check_cloexec(fd);
+	open_mutex_unlock();
+	return fd;
+}
+
+int open_fd_mode(const char *path, int flags, int mode)
+{
+	int fd;
+
+	open_mutex_lock();
+#if defined(O_CLOEXEC) && defined(SOCK_CLOEXEC)
+	if (cloexec_works != -1)
+		flags |= O_CLOEXEC;
+#endif
+	fd = open(path, flags, mode);
+	if (fd == -1) {
+		char buf[MAX_ERR_BUF];
+		char *estr;
+
+		open_mutex_unlock();
+		estr = strerror_r(errno, buf, sizeof(buf));
+		logerr("failed to open file: %s", estr);
+		return -1;
+	}
+	check_cloexec(fd);
+	open_mutex_unlock();
+	return fd;
+}
+
+int open_pipe(int pipefd[2])
+{
+	char buf[MAX_ERR_BUF];
+	char *estr;
+	int ret;
+
+	open_mutex_lock();
+#if defined(O_CLOEXEC) && defined(SOCK_CLOEXEC) && defined(HAVE_PIPE2)
+	if (cloexec_works != -1) {
+		ret = pipe2(pipefd, O_CLOEXEC);
+		if (ret != -1)
+			goto done;
+		if (errno != EINVAL)
+			goto err;
+	}
+#endif
+	ret = pipe(pipefd);
+	if (ret == -1)
+		goto err;
+	check_cloexec(pipefd[0]);
+	check_cloexec(pipefd[1]);
+#if defined(O_CLOEXEC) && defined(SOCK_CLOEXEC) && defined(HAVE_PIPE2)
+done:
+#endif
+	open_mutex_unlock();
+	return 0;
+err:
+	open_mutex_unlock();
+	estr = strerror_r(errno, buf, sizeof(buf));
+	logerr("failed to open pipe: %s", estr);
+	return -1;
+}
+
+int open_sock(int domain, int type, int protocol)
+{
+	int fd;
+
+	open_mutex_lock();
+#ifdef SOCK_CLOEXEC
+	if (cloexec_works != -1)
+		type |= SOCK_CLOEXEC;
+#endif
+	fd = socket(domain, type, protocol);
+	if (fd == -1) {
+		char buf[MAX_ERR_BUF];
+		char *estr;
+
+		open_mutex_unlock();
+		estr = strerror_r(errno, buf, sizeof(buf));
+		logerr("failed to open socket: %s", estr);
+		return -1;
+	}
+	check_cloexec(fd);
+	open_mutex_unlock();
+	return fd;
+}
+
+FILE *open_fopen_r(const char *path)
+{
+	FILE *f;
+
+	open_mutex_lock();
+#if defined(O_CLOEXEC) && defined(SOCK_CLOEXEC)
+	if (cloexec_works != -1) {
+		f = fopen(path, "re");
+		if (f != NULL) {
+			check_cloexec(fileno(f));
+			open_mutex_unlock();
+			return f;
+		}
+	}
+#endif
+	f = fopen(path, "r");
+	if (f == NULL) {
+		char buf[MAX_ERR_BUF];
+		char *estr;
+
+		open_mutex_unlock();
+		estr = strerror_r(errno, buf, sizeof(buf));
+		logerr("failed to open file: %s", estr);
+		return NULL;
+	}
+	check_cloexec(fileno(f));
+	open_mutex_unlock();
+	return f;
+}
+
+FILE *open_setmntent_r(const char *table)
+{
+	FILE *tab;
+
+	open_mutex_lock();
+#if defined(O_CLOEXEC) && defined(SOCK_CLOEXEC)
+	if (cloexec_works != -1) {
+		tab = setmntent(table, "re");
+		if (tab != NULL) {
+			check_cloexec(fileno(tab));
+			open_mutex_unlock();
+			return tab;
+		}
+	}
+#endif
+	tab = fopen(table, "r");
+	if (tab == NULL) {
+		char buf[MAX_ERR_BUF];
+		char *estr;
+
+		open_mutex_unlock();
+		estr = strerror_r(errno, buf, sizeof(buf));
+		logerr("failed to open mount table: %s", estr);
+		return NULL;
+	}
+	check_cloexec(fileno(tab));
+	open_mutex_unlock();
+	return tab;
+}
