* posix_spawn fixes
@ 2019-06-10 15:29 Bruno Haible
0 siblings, 0 replies; only message in thread
From: Bruno Haible @ 2019-06-10 15:29 UTC (permalink / raw)
To: bug-gnulib
[-- Attachment #1: Type: text/plain, Size: 2693 bytes --]
2019-06-10 Bruno Haible <bruno@clisp.org>
doc: Document existence of posix_spawn_file_actions_addchdir module.
* doc/glibc-functions/posix_spawn_file_actions_addchdir_np.texi: Mention
the posix_spawn_file_actions_addchdir module.
2019-06-10 Bruno Haible <bruno@clisp.org>
posix_spawn_file_actions_addfchdir: New module.
* lib/spawn.in.h (posix_spawn_file_actions_addfchdir): New declaration.
* lib/spawn_int.h (struct __spawn_action): Add tag 'spawn_do_fchdir' and
union member 'fchdir_action'.
* lib/spawn_faction_addfchdir.c: New file.
* lib/spawni.c (__spawni): Implement the spawn_do_fchdir action.
* m4/posix_spawn_faction_addfchdir.m4: New file.
* m4/posix_spawn.m4 (gl_POSIX_SPAWN_BODY): Test whether module
'posix_spawn_file_actions_addfchdir' is present and whether
posix_spawn_file_actions_addfchdir_np exists. Set REPLACE_POSIX_SPAWN.
* m4/spawn_h.m4 (gl_SPAWN_H): Test whether
posix_spawn_file_actions_addfchdir is declared.
(gl_SPAWN_H_DEFAULTS): Initialize
GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR,
HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR,
REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR.
* modules/spawn (Makefile.am): Substitute
GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR,
HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR,
REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR.
* modules/posix_spawn_file_actions_addfchdir: New file.
* tests/test-spawn-c++.cc (posix_spawn_file_actions_addfchdir): Check
signature.
* doc/posix-functions/posix_spawn.texi: Mention the new module.
* doc/posix-functions/posix_spawnp.texi: Likewise.
* doc/glibc-functions/posix_spawn_file_actions_addfchdir_np.texi:
Likewise.
2019-06-10 Bruno Haible <bruno@clisp.org>
posix_spawn_file_actions_addfchdir: Add tests.
* tests/test-posix_spawn_file_actions_addfchdir.c: New file.
* tests/test-posix_spawn5.c: New file.
* modules/posix_spawn_file_actions_addfchdir-tests: New file.
2019-06-10 Bruno Haible <bruno@clisp.org>
posix_spawn_file_actions_addopen: Fix possible use-after-free bug.
Reported at <https://sourceware.org/bugzilla/show_bug.cgi?id=17048>.
* lib/spawn_int.h (struct __spawn_action): Remove 'const' from path.
* lib/spawn_faction_addopen.c (posix_spawn_file_actions_addopen): Make
a copy of the path argument.
* lib/spawn_faction_destroy.c (posix_spawn_file_actions_destroy): Free
it.
2019-06-10 Bruno Haible <bruno@clisp.org>
posix_spawn_file_actions_addchdir: Fix possible use-after-free bug.
* lib/spawn_int.h (struct __spawn_action): Remove 'const' from path.
* lib/spawn_faction_addchdir.c (posix_spawn_file_actions_addchdir): Make
a copy of the path argument.
* lib/spawn_faction_destroy.c (posix_spawn_file_actions_destroy): Free
it.
[-- Attachment #2: 0001-doc-Document-existence-of-posix_spawn_file_actions_a.patch --]
[-- Type: text/x-patch, Size: 1866 bytes --]
From 2ad7a33b829d0378fb6765e778e4170a3fec9697 Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Mon, 10 Jun 2019 16:26:03 +0200
Subject: [PATCH 1/5] doc: Document existence of
posix_spawn_file_actions_addchdir module.
* doc/glibc-functions/posix_spawn_file_actions_addchdir_np.texi: Mention
the posix_spawn_file_actions_addchdir module.
---
ChangeLog | 6 ++++++
doc/glibc-functions/posix_spawn_file_actions_addchdir_np.texi | 3 +++
2 files changed, 9 insertions(+)
diff --git a/ChangeLog b/ChangeLog
index d1b8854..ac79aac 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
2019-06-10 Bruno Haible <bruno@clisp.org>
+ doc: Document existence of posix_spawn_file_actions_addchdir module.
+ * doc/glibc-functions/posix_spawn_file_actions_addchdir_np.texi: Mention
+ the posix_spawn_file_actions_addchdir module.
+
+2019-06-10 Bruno Haible <bruno@clisp.org>
+
posix_spawn-internal: Fix module description.
* modules/posix_spawn (configure.ac): Move request to compile spawni.c
from here...
diff --git a/doc/glibc-functions/posix_spawn_file_actions_addchdir_np.texi b/doc/glibc-functions/posix_spawn_file_actions_addchdir_np.texi
index a40a3d7..1c4c0a4 100644
--- a/doc/glibc-functions/posix_spawn_file_actions_addchdir_np.texi
+++ b/doc/glibc-functions/posix_spawn_file_actions_addchdir_np.texi
@@ -14,3 +14,6 @@ Portability problems not fixed by Gnulib:
This function is missing on many non-glibc platforms:
glibc 2.28, Mac OS X 10.5, FreeBSD 12.0, NetBSD 5.0, OpenBSD 3.8, Minix 3.1.8, AIX 7.1, HP-UX 11.31, IRIX 6.5, OSF/1 5.1, Solaris 11.0, Cygwin, mingw, MSVC 14, Interix 3.5, BeOS, Android 9.0.
@end itemize
+
+Note: Gnulib has a module @code{posix_spawn_file_actions_addchdir} that
+provides equivalent functionality, just without the suffix @code{_np}.
--
2.7.4
[-- Attachment #3: 0002-posix_spawn_file_actions_addfchdir-New-module.patch --]
[-- Type: text/x-patch, Size: 24402 bytes --]
From d822de87e4d1c97e422e48332542dfe7261c7d82 Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Mon, 10 Jun 2019 16:16:16 +0200
Subject: [PATCH 2/5] posix_spawn_file_actions_addfchdir: New module.
* lib/spawn.in.h (posix_spawn_file_actions_addfchdir): New declaration.
* lib/spawn_int.h (struct __spawn_action): Add tag 'spawn_do_fchdir' and
union member 'fchdir_action'.
* lib/spawn_faction_addfchdir.c: New file.
* lib/spawni.c (__spawni): Implement the spawn_do_fchdir action.
* m4/posix_spawn_faction_addfchdir.m4: New file.
* m4/posix_spawn.m4 (gl_POSIX_SPAWN_BODY): Test whether module
'posix_spawn_file_actions_addfchdir' is present and whether
posix_spawn_file_actions_addfchdir_np exists. Set REPLACE_POSIX_SPAWN.
* m4/spawn_h.m4 (gl_SPAWN_H): Test whether
posix_spawn_file_actions_addfchdir is declared.
(gl_SPAWN_H_DEFAULTS): Initialize
GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR,
HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR,
REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR.
* modules/spawn (Makefile.am): Substitute
GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR,
HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR,
REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR.
* modules/posix_spawn_file_actions_addfchdir: New file.
* tests/test-spawn-c++.cc (posix_spawn_file_actions_addfchdir): Check
signature.
* doc/posix-functions/posix_spawn.texi: Mention the new module.
* doc/posix-functions/posix_spawnp.texi: Likewise.
* doc/glibc-functions/posix_spawn_file_actions_addfchdir_np.texi:
Likewise.
---
ChangeLog | 30 ++++++++++
.../posix_spawn_file_actions_addfchdir_np.texi | 3 +
doc/posix-functions/posix_spawn.texi | 7 ++-
doc/posix-functions/posix_spawnp.texi | 7 ++-
lib/spawn.in.h | 35 +++++++++++
lib/spawn_faction_addfchdir.c | 68 ++++++++++++++++++++++
lib/spawn_int.h | 7 ++-
lib/spawni.c | 6 ++
m4/posix_spawn.m4 | 11 +++-
m4/posix_spawn_faction_addfchdir.m4 | 20 +++++++
m4/spawn_h.m4 | 54 +++++++++--------
modules/posix_spawn_file_actions_addfchdir | 30 ++++++++++
modules/spawn | 3 +
tests/test-spawn-c++.cc | 5 ++
14 files changed, 254 insertions(+), 32 deletions(-)
create mode 100644 lib/spawn_faction_addfchdir.c
create mode 100644 m4/posix_spawn_faction_addfchdir.m4
create mode 100644 modules/posix_spawn_file_actions_addfchdir
diff --git a/ChangeLog b/ChangeLog
index ac79aac..ecf1d47 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,35 @@
2019-06-10 Bruno Haible <bruno@clisp.org>
+ posix_spawn_file_actions_addfchdir: New module.
+ * lib/spawn.in.h (posix_spawn_file_actions_addfchdir): New declaration.
+ * lib/spawn_int.h (struct __spawn_action): Add tag 'spawn_do_fchdir' and
+ union member 'fchdir_action'.
+ * lib/spawn_faction_addfchdir.c: New file.
+ * lib/spawni.c (__spawni): Implement the spawn_do_fchdir action.
+ * m4/posix_spawn_faction_addfchdir.m4: New file.
+ * m4/posix_spawn.m4 (gl_POSIX_SPAWN_BODY): Test whether module
+ 'posix_spawn_file_actions_addfchdir' is present and whether
+ posix_spawn_file_actions_addfchdir_np exists. Set REPLACE_POSIX_SPAWN.
+ * m4/spawn_h.m4 (gl_SPAWN_H): Test whether
+ posix_spawn_file_actions_addfchdir is declared.
+ (gl_SPAWN_H_DEFAULTS): Initialize
+ GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR,
+ HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR,
+ REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR.
+ * modules/spawn (Makefile.am): Substitute
+ GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR,
+ HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR,
+ REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR.
+ * modules/posix_spawn_file_actions_addfchdir: New file.
+ * tests/test-spawn-c++.cc (posix_spawn_file_actions_addfchdir): Check
+ signature.
+ * doc/posix-functions/posix_spawn.texi: Mention the new module.
+ * doc/posix-functions/posix_spawnp.texi: Likewise.
+ * doc/glibc-functions/posix_spawn_file_actions_addfchdir_np.texi:
+ Likewise.
+
+2019-06-10 Bruno Haible <bruno@clisp.org>
+
doc: Document existence of posix_spawn_file_actions_addchdir module.
* doc/glibc-functions/posix_spawn_file_actions_addchdir_np.texi: Mention
the posix_spawn_file_actions_addchdir module.
diff --git a/doc/glibc-functions/posix_spawn_file_actions_addfchdir_np.texi b/doc/glibc-functions/posix_spawn_file_actions_addfchdir_np.texi
index bb82195..6da90fd 100644
--- a/doc/glibc-functions/posix_spawn_file_actions_addfchdir_np.texi
+++ b/doc/glibc-functions/posix_spawn_file_actions_addfchdir_np.texi
@@ -14,3 +14,6 @@ Portability problems not fixed by Gnulib:
This function is missing on all non-glibc platforms:
glibc 2.28, Mac OS X 10.5, FreeBSD 12.0, NetBSD 5.0, OpenBSD 3.8, Minix 3.1.8, AIX 7.1, HP-UX 11.31, IRIX 6.5, OSF/1 5.1, Solaris 11.4, Cygwin, mingw, MSVC 14, Interix 3.5, BeOS, Android 9.0.
@end itemize
+
+Note: Gnulib has a module @code{posix_spawn_file_actions_addfchdir} that
+provides equivalent functionality, just without the suffix @code{_np}.
diff --git a/doc/posix-functions/posix_spawn.texi b/doc/posix-functions/posix_spawn.texi
index bed0e79..6513608 100644
--- a/doc/posix-functions/posix_spawn.texi
+++ b/doc/posix-functions/posix_spawn.texi
@@ -24,6 +24,7 @@ This function does not work on some platforms:
AIX 6.1 (under particular circumstances), mingw.
@end itemize
-The Gnulib module @code{posix_spawn_file_actions_addchdir} provides an
-additional action, that consists in changing the current directory of
-the child process before starting the specified program.
+The Gnulib modules @code{posix_spawn_file_actions_addchdir} and
+@code{posix_spawn_file_actions_addfchdir} provide additional actions,
+that consist in changing the current directory of the child process
+before starting the specified program.
diff --git a/doc/posix-functions/posix_spawnp.texi b/doc/posix-functions/posix_spawnp.texi
index 6cfec28..3dd8ed4 100644
--- a/doc/posix-functions/posix_spawnp.texi
+++ b/doc/posix-functions/posix_spawnp.texi
@@ -24,6 +24,7 @@ This function does not work on some platforms:
AIX 6.1 (under particular circumstances), mingw.
@end itemize
-The Gnulib module @code{posix_spawn_file_actions_addchdir} provides an
-additional action, that consists in changing the current directory of
-the child process before starting the specified program.
+The Gnulib modules @code{posix_spawn_file_actions_addchdir} and
+@code{posix_spawn_file_actions_addfchdir} provide additional actions,
+that consist in changing the current directory of the child process
+before starting the specified program.
diff --git a/lib/spawn.in.h b/lib/spawn.in.h
index df95e4a..721d70f 100644
--- a/lib/spawn.in.h
+++ b/lib/spawn.in.h
@@ -913,6 +913,41 @@ _GL_WARN_ON_USE (posix_spawn_file_actions_addchdir,
# endif
#endif
+#if @GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR@
+/* Add an action to FILE-ACTIONS which tells the implementation to call
+ 'fchdir' to the given directory during the 'spawn' call. */
+# if @REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+# define posix_spawn_file_actions_addfchdir rpl_posix_spawn_file_actions_addfchdir
+# endif
+_GL_FUNCDECL_RPL (posix_spawn_file_actions_addfchdir, int,
+ (posix_spawn_file_actions_t *_Restrict_ __file_actions,
+ int __fd)
+ __THROW _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (posix_spawn_file_actions_addfchdir, int,
+ (posix_spawn_file_actions_t *_Restrict_ __file_actions,
+ int __fd));
+# else
+# if !@HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR@
+_GL_FUNCDECL_SYS (posix_spawn_file_actions_addfchdir, int,
+ (posix_spawn_file_actions_t *_Restrict_ __file_actions,
+ int __fd)
+ __THROW _GL_ARG_NONNULL ((1)));
+# endif
+_GL_CXXALIAS_SYS (posix_spawn_file_actions_addfchdir, int,
+ (posix_spawn_file_actions_t *_Restrict_ __file_actions,
+ int __fd));
+# endif
+_GL_CXXALIASWARN (posix_spawn_file_actions_addfchdir);
+#elif defined GNULIB_POSIXCHECK
+# undef posix_spawn_file_actions_addfchdir
+# if HAVE_RAW_DECL_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR
+_GL_WARN_ON_USE (posix_spawn_file_actions_addfchdir,
+ "posix_spawn_file_actions_addfchdir is unportable - "
+ "use gnulib module posix_spawn_file_actions_addfchdir for portability");
+# endif
+#endif
+
#endif /* _@GUARD_PREFIX@_SPAWN_H */
#endif /* _@GUARD_PREFIX@_SPAWN_H */
diff --git a/lib/spawn_faction_addfchdir.c b/lib/spawn_faction_addfchdir.c
new file mode 100644
index 0000000..504856d
--- /dev/null
+++ b/lib/spawn_faction_addfchdir.c
@@ -0,0 +1,68 @@
+/* Copyright (C) 2018-2019 Free Software Foundation, Inc.
+
+ 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 <https://www.gnu.org/licenses/>. */
+
+#include <config.h>
+
+/* Specification. */
+#include <spawn.h>
+
+#include <errno.h>
+#include <unistd.h>
+
+#if !_LIBC
+# define __sysconf(open_max) getdtablesize ()
+#endif
+
+#if REPLACE_POSIX_SPAWN
+# include "spawn_int.h"
+#endif
+
+/* Add an action to FILE-ACTIONS which tells the implementation to call
+ 'fchdir' to the given directory during the 'spawn' call. */
+int
+posix_spawn_file_actions_addfchdir (posix_spawn_file_actions_t *file_actions,
+ int fd)
+#undef posix_spawn_file_actions_addfchdir
+{
+ int maxfd = __sysconf (_SC_OPEN_MAX);
+
+ /* Test for the validity of the file descriptor. */
+ if (fd < 0 || fd >= maxfd)
+ return EBADF;
+
+#if !REPLACE_POSIX_SPAWN
+ return posix_spawn_file_actions_addfchdir_np (file_actions, fd);
+#else
+ /* Allocate more memory if needed. */
+ if (file_actions->_used == file_actions->_allocated
+ && __posix_spawn_file_actions_realloc (file_actions) != 0)
+ /* This can only mean we ran out of memory. */
+ return ENOMEM;
+
+ {
+ struct __spawn_action *rec;
+
+ /* Add the new value. */
+ rec = &file_actions->_actions[file_actions->_used];
+ rec->tag = spawn_do_fchdir;
+ rec->action.fchdir_action.fd = fd;
+
+ /* Account for the new entry. */
+ ++file_actions->_used;
+
+ return 0;
+ }
+#endif
+}
diff --git a/lib/spawn_int.h b/lib/spawn_int.h
index 06b8004..584c1bb 100644
--- a/lib/spawn_int.h
+++ b/lib/spawn_int.h
@@ -24,7 +24,8 @@ struct __spawn_action
spawn_do_close,
spawn_do_dup2,
spawn_do_open,
- spawn_do_chdir
+ spawn_do_chdir,
+ spawn_do_fchdir
} tag;
union
@@ -49,6 +50,10 @@ struct __spawn_action
{
const char *path;
} chdir_action;
+ struct
+ {
+ int fd;
+ } fchdir_action;
} action;
};
diff --git a/lib/spawni.c b/lib/spawni.c
index 39e99a0..087f45c 100644
--- a/lib/spawni.c
+++ b/lib/spawni.c
@@ -290,6 +290,12 @@ __spawni (pid_t *pid, const char *file,
/* The 'chdir' call failed. */
_exit (SPAWN_ERROR);
break;
+
+ case spawn_do_fchdir:
+ if (fchdir (action->action.fchdir_action.fd) < 0)
+ /* The 'fchdir' call failed. */
+ _exit (SPAWN_ERROR);
+ break;
}
}
}
diff --git a/m4/posix_spawn.m4 b/m4/posix_spawn.m4
index d50dcc9..0128390 100644
--- a/m4/posix_spawn.m4
+++ b/m4/posix_spawn.m4
@@ -1,4 +1,4 @@
-# posix_spawn.m4 serial 16
+# posix_spawn.m4 serial 17
dnl Copyright (C) 2008-2019 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -42,6 +42,15 @@ AC_DEFUN([gl_POSIX_SPAWN_BODY],
REPLACE_POSIX_SPAWN=1
fi
])
+ m4_ifdef([gl_FUNC_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR],
+ [dnl Module 'posix_spawn_file_actions_addfchdir' is present.
+ AC_CHECK_FUNCS_ONCE([posix_spawn_file_actions_addfchdir_np])
+ if test $ac_cv_func_posix_spawn_file_actions_addfchdir_np = no; then
+ dnl In order to implement the posix_spawn_file_actions_addfchdir
+ dnl function, we need to replace the entire posix_spawn facility.
+ REPLACE_POSIX_SPAWN=1
+ fi
+ ])
if test $REPLACE_POSIX_SPAWN = 0; then
gl_POSIX_SPAWN_WORKS
case "$gl_cv_func_posix_spawn_works" in
diff --git a/m4/posix_spawn_faction_addfchdir.m4 b/m4/posix_spawn_faction_addfchdir.m4
new file mode 100644
index 0000000..ef2f9d6
--- /dev/null
+++ b/m4/posix_spawn_faction_addfchdir.m4
@@ -0,0 +1,20 @@
+# posix_spawn_faction_addfchdir.m4 serial 1
+dnl Copyright (C) 2018-2019 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_FUNC_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR],
+[
+ AC_REQUIRE([gl_SPAWN_H_DEFAULTS])
+ AC_REQUIRE([AC_PROG_CC])
+ gl_POSIX_SPAWN
+ AC_CHECK_FUNCS_ONCE([posix_spawn_file_actions_addfchdir posix_spawn_file_actions_addfchdir_np])
+ if test $ac_cv_func_posix_spawn_file_actions_addfchdir = yes; then
+ dnl This function is not yet standardized. Therefore override the
+ dnl system's implementation always.
+ REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR=1
+ else
+ HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR=0
+ fi
+])
diff --git a/m4/spawn_h.m4 b/m4/spawn_h.m4
index 561caa7..95cb25d 100644
--- a/m4/spawn_h.m4
+++ b/m4/spawn_h.m4
@@ -1,4 +1,4 @@
-# spawn_h.m4 serial 17
+# spawn_h.m4 serial 18
dnl Copyright (C) 2008-2019 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -53,7 +53,8 @@ AC_DEFUN([gl_SPAWN_H],
posix_spawnattr_getschedparam posix_spawnattr_setschedparam
posix_spawn_file_actions_init posix_spawn_file_actions_destroy
posix_spawn_file_actions_addopen posix_spawn_file_actions_addclose
- posix_spawn_file_actions_adddup2 posix_spawn_file_actions_addchdir])
+ posix_spawn_file_actions_adddup2 posix_spawn_file_actions_addchdir
+ posix_spawn_file_actions_addfchdir])
])
dnl Checks whether the system has the functions posix_spawn.
@@ -89,28 +90,29 @@ AC_DEFUN([gl_SPAWN_MODULE_INDICATOR],
AC_DEFUN([gl_SPAWN_H_DEFAULTS],
[
- GNULIB_POSIX_SPAWN=0; AC_SUBST([GNULIB_POSIX_SPAWN])
- GNULIB_POSIX_SPAWNP=0; AC_SUBST([GNULIB_POSIX_SPAWNP])
- GNULIB_POSIX_SPAWN_FILE_ACTIONS_INIT=0; AC_SUBST([GNULIB_POSIX_SPAWN_FILE_ACTIONS_INIT])
- GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR=0; AC_SUBST([GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR])
- GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE=0; AC_SUBST([GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE])
- GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2=0; AC_SUBST([GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2])
- GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN=0; AC_SUBST([GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN])
- GNULIB_POSIX_SPAWN_FILE_ACTIONS_DESTROY=0; AC_SUBST([GNULIB_POSIX_SPAWN_FILE_ACTIONS_DESTROY])
- GNULIB_POSIX_SPAWNATTR_INIT=0; AC_SUBST([GNULIB_POSIX_SPAWNATTR_INIT])
- GNULIB_POSIX_SPAWNATTR_GETFLAGS=0; AC_SUBST([GNULIB_POSIX_SPAWNATTR_GETFLAGS])
- GNULIB_POSIX_SPAWNATTR_SETFLAGS=0; AC_SUBST([GNULIB_POSIX_SPAWNATTR_SETFLAGS])
- GNULIB_POSIX_SPAWNATTR_GETPGROUP=0; AC_SUBST([GNULIB_POSIX_SPAWNATTR_GETPGROUP])
- GNULIB_POSIX_SPAWNATTR_SETPGROUP=0; AC_SUBST([GNULIB_POSIX_SPAWNATTR_SETPGROUP])
- GNULIB_POSIX_SPAWNATTR_GETSCHEDPARAM=0; AC_SUBST([GNULIB_POSIX_SPAWNATTR_GETSCHEDPARAM])
- GNULIB_POSIX_SPAWNATTR_SETSCHEDPARAM=0; AC_SUBST([GNULIB_POSIX_SPAWNATTR_SETSCHEDPARAM])
- GNULIB_POSIX_SPAWNATTR_GETSCHEDPOLICY=0; AC_SUBST([GNULIB_POSIX_SPAWNATTR_GETSCHEDPOLICY])
- GNULIB_POSIX_SPAWNATTR_SETSCHEDPOLICY=0; AC_SUBST([GNULIB_POSIX_SPAWNATTR_SETSCHEDPOLICY])
- GNULIB_POSIX_SPAWNATTR_GETSIGDEFAULT=0; AC_SUBST([GNULIB_POSIX_SPAWNATTR_GETSIGDEFAULT])
- GNULIB_POSIX_SPAWNATTR_SETSIGDEFAULT=0; AC_SUBST([GNULIB_POSIX_SPAWNATTR_SETSIGDEFAULT])
- GNULIB_POSIX_SPAWNATTR_GETSIGMASK=0; AC_SUBST([GNULIB_POSIX_SPAWNATTR_GETSIGMASK])
- GNULIB_POSIX_SPAWNATTR_SETSIGMASK=0; AC_SUBST([GNULIB_POSIX_SPAWNATTR_SETSIGMASK])
- GNULIB_POSIX_SPAWNATTR_DESTROY=0; AC_SUBST([GNULIB_POSIX_SPAWNATTR_DESTROY])
+ GNULIB_POSIX_SPAWN=0; AC_SUBST([GNULIB_POSIX_SPAWN])
+ GNULIB_POSIX_SPAWNP=0; AC_SUBST([GNULIB_POSIX_SPAWNP])
+ GNULIB_POSIX_SPAWN_FILE_ACTIONS_INIT=0; AC_SUBST([GNULIB_POSIX_SPAWN_FILE_ACTIONS_INIT])
+ GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR=0; AC_SUBST([GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR])
+ GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE=0; AC_SUBST([GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE])
+ GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2=0; AC_SUBST([GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2])
+ GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR=0; AC_SUBST([GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR])
+ GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN=0; AC_SUBST([GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN])
+ GNULIB_POSIX_SPAWN_FILE_ACTIONS_DESTROY=0; AC_SUBST([GNULIB_POSIX_SPAWN_FILE_ACTIONS_DESTROY])
+ GNULIB_POSIX_SPAWNATTR_INIT=0; AC_SUBST([GNULIB_POSIX_SPAWNATTR_INIT])
+ GNULIB_POSIX_SPAWNATTR_GETFLAGS=0; AC_SUBST([GNULIB_POSIX_SPAWNATTR_GETFLAGS])
+ GNULIB_POSIX_SPAWNATTR_SETFLAGS=0; AC_SUBST([GNULIB_POSIX_SPAWNATTR_SETFLAGS])
+ GNULIB_POSIX_SPAWNATTR_GETPGROUP=0; AC_SUBST([GNULIB_POSIX_SPAWNATTR_GETPGROUP])
+ GNULIB_POSIX_SPAWNATTR_SETPGROUP=0; AC_SUBST([GNULIB_POSIX_SPAWNATTR_SETPGROUP])
+ GNULIB_POSIX_SPAWNATTR_GETSCHEDPARAM=0; AC_SUBST([GNULIB_POSIX_SPAWNATTR_GETSCHEDPARAM])
+ GNULIB_POSIX_SPAWNATTR_SETSCHEDPARAM=0; AC_SUBST([GNULIB_POSIX_SPAWNATTR_SETSCHEDPARAM])
+ GNULIB_POSIX_SPAWNATTR_GETSCHEDPOLICY=0; AC_SUBST([GNULIB_POSIX_SPAWNATTR_GETSCHEDPOLICY])
+ GNULIB_POSIX_SPAWNATTR_SETSCHEDPOLICY=0; AC_SUBST([GNULIB_POSIX_SPAWNATTR_SETSCHEDPOLICY])
+ GNULIB_POSIX_SPAWNATTR_GETSIGDEFAULT=0; AC_SUBST([GNULIB_POSIX_SPAWNATTR_GETSIGDEFAULT])
+ GNULIB_POSIX_SPAWNATTR_SETSIGDEFAULT=0; AC_SUBST([GNULIB_POSIX_SPAWNATTR_SETSIGDEFAULT])
+ GNULIB_POSIX_SPAWNATTR_GETSIGMASK=0; AC_SUBST([GNULIB_POSIX_SPAWNATTR_GETSIGMASK])
+ GNULIB_POSIX_SPAWNATTR_SETSIGMASK=0; AC_SUBST([GNULIB_POSIX_SPAWNATTR_SETSIGMASK])
+ GNULIB_POSIX_SPAWNATTR_DESTROY=0; AC_SUBST([GNULIB_POSIX_SPAWNATTR_DESTROY])
dnl Assume proper GNU behavior unless another module says otherwise.
HAVE_POSIX_SPAWN=1; AC_SUBST([HAVE_POSIX_SPAWN])
HAVE_POSIX_SPAWNATTR_T=1; AC_SUBST([HAVE_POSIX_SPAWNATTR_T])
@@ -118,6 +120,8 @@ AC_DEFUN([gl_SPAWN_H_DEFAULTS],
AC_SUBST([HAVE_POSIX_SPAWN_FILE_ACTIONS_T])
HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR=1;
AC_SUBST([HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR])
+ HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR=1;
+ AC_SUBST([HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR])
REPLACE_POSIX_SPAWN=0; AC_SUBST([REPLACE_POSIX_SPAWN])
REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR=0;
AC_SUBST([REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR])
@@ -125,6 +129,8 @@ AC_DEFUN([gl_SPAWN_H_DEFAULTS],
AC_SUBST([REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE])
REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2=0;
AC_SUBST([REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2])
+ REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR=0;
+ AC_SUBST([REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR])
REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN=0;
AC_SUBST([REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN])
])
diff --git a/modules/posix_spawn_file_actions_addfchdir b/modules/posix_spawn_file_actions_addfchdir
new file mode 100644
index 0000000..cd9cb99
--- /dev/null
+++ b/modules/posix_spawn_file_actions_addfchdir
@@ -0,0 +1,30 @@
+Description:
+posix_spawn_file_actions_addfchdir() function: augment a child process actions
+specification.
+
+Files:
+lib/spawn_faction_addfchdir.c
+lib/spawn_int.h
+m4/posix_spawn_faction_addfchdir.m4
+
+Depends-on:
+spawn
+posix_spawn_file_actions_init [test $HAVE_POSIX_SPAWN = 0 || test $REPLACE_POSIX_SPAWN = 1 || test $HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR = 0 || test $REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR = 1]
+
+configure.ac:
+gl_FUNC_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR
+if test $HAVE_POSIX_SPAWN = 0 || test $REPLACE_POSIX_SPAWN = 1 || test $HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR = 0 || test $REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR = 1; then
+ AC_LIBOBJ([spawn_faction_addfchdir])
+fi
+gl_SPAWN_MODULE_INDICATOR([posix_spawn_file_actions_addfchdir])
+
+Makefile.am:
+
+Include:
+<spawn.h>
+
+License:
+LGPLv2+
+
+Maintainer:
+all
diff --git a/modules/spawn b/modules/spawn
index dc861d3..6e03294 100644
--- a/modules/spawn
+++ b/modules/spawn
@@ -35,6 +35,7 @@ spawn.h: spawn.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H)
-e 's/@''GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR''@/$(GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR)/g' \
-e 's/@''GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE''@/$(GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE)/g' \
-e 's/@''GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2''@/$(GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2)/g' \
+ -e 's/@''GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR''@/$(GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR)/g' \
-e 's/@''GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN''@/$(GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN)/g' \
-e 's/@''GNULIB_POSIX_SPAWN_FILE_ACTIONS_DESTROY''@/$(GNULIB_POSIX_SPAWN_FILE_ACTIONS_DESTROY)/g' \
-e 's/@''GNULIB_POSIX_SPAWNATTR_INIT''@/$(GNULIB_POSIX_SPAWNATTR_INIT)/g' \
@@ -55,10 +56,12 @@ spawn.h: spawn.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H)
-e 's|@''HAVE_POSIX_SPAWNATTR_T''@|$(HAVE_POSIX_SPAWNATTR_T)|g' \
-e 's|@''HAVE_POSIX_SPAWN_FILE_ACTIONS_T''@|$(HAVE_POSIX_SPAWN_FILE_ACTIONS_T)|g' \
-e 's|@''HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR''@|$(HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR)|g' \
+ -e 's|@''HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR''@|$(HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR)|g' \
-e 's|@''REPLACE_POSIX_SPAWN''@|$(REPLACE_POSIX_SPAWN)|g' \
-e 's|@''REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR''@|$(REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR)|g' \
-e 's|@''REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE''@|$(REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE)|g' \
-e 's|@''REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2''@|$(REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2)|g' \
+ -e 's|@''REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR''@|$(REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR)|g' \
-e 's|@''REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN''@|$(REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN)|g' \
-e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
-e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \
diff --git a/tests/test-spawn-c++.cc b/tests/test-spawn-c++.cc
index 2ba1cc4..119917f 100644
--- a/tests/test-spawn-c++.cc
+++ b/tests/test-spawn-c++.cc
@@ -137,6 +137,11 @@ SIGNATURE_CHECK (GNULIB_NAMESPACE::posix_spawn_file_actions_addchdir, int,
(posix_spawn_file_actions_t *, const char *));
#endif
+#if GNULIB_TEST_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR
+SIGNATURE_CHECK (GNULIB_NAMESPACE::posix_spawn_file_actions_addfchdir, int,
+ (posix_spawn_file_actions_t *, int));
+#endif
+
int
main ()
--
2.7.4
[-- Attachment #4: 0003-posix_spawn_file_actions_addfchdir-Add-tests.patch --]
[-- Type: text/x-patch, Size: 8418 bytes --]
From fbb40ec10e333cff0b9845572065edd9e66eac79 Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Mon, 10 Jun 2019 16:17:35 +0200
Subject: [PATCH 3/5] posix_spawn_file_actions_addfchdir: Add tests.
* tests/test-posix_spawn_file_actions_addfchdir.c: New file.
* tests/test-posix_spawn5.c: New file.
* modules/posix_spawn_file_actions_addfchdir-tests: New file.
---
ChangeLog | 7 ++
modules/posix_spawn_file_actions_addfchdir-tests | 20 +++
tests/test-posix_spawn5.c | 148 +++++++++++++++++++++++
tests/test-posix_spawn_file_actions_addfchdir.c | 44 +++++++
4 files changed, 219 insertions(+)
create mode 100644 modules/posix_spawn_file_actions_addfchdir-tests
create mode 100644 tests/test-posix_spawn5.c
create mode 100644 tests/test-posix_spawn_file_actions_addfchdir.c
diff --git a/ChangeLog b/ChangeLog
index ecf1d47..7bbf5fa 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,12 @@
2019-06-10 Bruno Haible <bruno@clisp.org>
+ posix_spawn_file_actions_addfchdir: Add tests.
+ * tests/test-posix_spawn_file_actions_addfchdir.c: New file.
+ * tests/test-posix_spawn5.c: New file.
+ * modules/posix_spawn_file_actions_addfchdir-tests: New file.
+
+2019-06-10 Bruno Haible <bruno@clisp.org>
+
posix_spawn_file_actions_addfchdir: New module.
* lib/spawn.in.h (posix_spawn_file_actions_addfchdir): New declaration.
* lib/spawn_int.h (struct __spawn_action): Add tag 'spawn_do_fchdir' and
diff --git a/modules/posix_spawn_file_actions_addfchdir-tests b/modules/posix_spawn_file_actions_addfchdir-tests
new file mode 100644
index 0000000..5e50695
--- /dev/null
+++ b/modules/posix_spawn_file_actions_addfchdir-tests
@@ -0,0 +1,20 @@
+Files:
+tests/test-posix_spawn_file_actions_addfchdir.c
+tests/test-posix_spawn5.c
+tests/signature.h
+tests/macros.h
+
+Depends-on:
+posix_spawn_file_actions_init
+posix_spawnp-tests
+
+configure.ac:
+
+Makefile.am:
+TESTS += test-posix_spawn_file_actions_addfchdir
+check_PROGRAMS += test-posix_spawn_file_actions_addfchdir
+
+if POSIX_SPAWN_PORTED
+TESTS += test-posix_spawn5
+check_PROGRAMS += test-posix_spawn5
+endif
diff --git a/tests/test-posix_spawn5.c b/tests/test-posix_spawn5.c
new file mode 100644
index 0000000..805f666
--- /dev/null
+++ b/tests/test-posix_spawn5.c
@@ -0,0 +1,148 @@
+/* Test of posix_spawn() function with 'fchdir' action.
+ Copyright (C) 2008-2019 Free Software Foundation, Inc.
+
+ 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 <https://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2018. */
+
+#include <config.h>
+
+#include <spawn.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+static int
+fd_safer (int fd)
+{
+ if (0 <= fd && fd <= 2)
+ {
+ int f = fd_safer (dup (fd));
+ int e = errno;
+ close (fd);
+ errno = e;
+ fd = f;
+ }
+
+ return fd;
+}
+
+int
+main ()
+{
+ char *argv[2] = { (char *) "pwd", NULL };
+ int rootfd;
+ int ifd[2];
+ sigset_t blocked_signals;
+ sigset_t fatal_signal_set;
+ posix_spawn_file_actions_t actions;
+ bool actions_allocated;
+ posix_spawnattr_t attrs;
+ bool attrs_allocated;
+ int err;
+ pid_t child;
+ int fd;
+ FILE *fp;
+ char line[80];
+ int status;
+ int exitstatus;
+
+ rootfd = open ("/", O_RDONLY);
+ if (rootfd < 0)
+ {
+ perror ("cannot open directory");
+ exit (1);
+ }
+ if (pipe (ifd) < 0 || (ifd[0] = fd_safer (ifd[0])) < 0)
+ {
+ perror ("cannot create pipe");
+ exit (1);
+ }
+ sigprocmask (SIG_SETMASK, NULL, &blocked_signals);
+ sigemptyset (&fatal_signal_set);
+ sigaddset (&fatal_signal_set, SIGINT);
+ sigaddset (&fatal_signal_set, SIGTERM);
+ sigaddset (&fatal_signal_set, SIGHUP);
+ sigaddset (&fatal_signal_set, SIGPIPE);
+ sigprocmask (SIG_BLOCK, &fatal_signal_set, NULL);
+ actions_allocated = false;
+ attrs_allocated = false;
+ if ((err = posix_spawn_file_actions_init (&actions)) != 0
+ || (actions_allocated = true,
+ (err = posix_spawn_file_actions_adddup2 (&actions, ifd[1], STDOUT_FILENO)) != 0
+ || (err = posix_spawn_file_actions_addclose (&actions, ifd[1])) != 0
+ || (err = posix_spawn_file_actions_addclose (&actions, ifd[0])) != 0
+ || (err = posix_spawn_file_actions_addopen (&actions, STDIN_FILENO, "/dev/null", O_RDONLY, 0)) != 0
+ || (err = posix_spawn_file_actions_addfchdir (&actions, rootfd)) != 0
+ || (err = posix_spawnattr_init (&attrs)) != 0
+ || (attrs_allocated = true,
+ (err = posix_spawnattr_setsigmask (&attrs, &blocked_signals)) != 0
+ || (err = posix_spawnattr_setflags (&attrs, POSIX_SPAWN_SETSIGMASK)) != 0)
+ || (err = posix_spawnp (&child, "pwd", &actions, &attrs, argv, environ)) != 0))
+ {
+ if (actions_allocated)
+ posix_spawn_file_actions_destroy (&actions);
+ if (attrs_allocated)
+ posix_spawnattr_destroy (&attrs);
+ sigprocmask (SIG_UNBLOCK, &fatal_signal_set, NULL);
+ errno = err;
+ perror ("subprocess failed");
+ exit (1);
+ }
+ posix_spawn_file_actions_destroy (&actions);
+ posix_spawnattr_destroy (&attrs);
+ sigprocmask (SIG_UNBLOCK, &fatal_signal_set, NULL);
+ close (ifd[1]);
+ fd = ifd[0];
+ fp = fdopen (fd, "r");
+ if (fp == NULL)
+ {
+ fprintf (stderr, "fdopen() failed\n");
+ exit (1);
+ }
+ if (fread (line, 1, 80, fp) < 2)
+ {
+ fprintf (stderr, "could not read expected output\n");
+ exit (1);
+ }
+ if (memcmp (line, "/\n", 2) != 0)
+ {
+ fprintf (stderr, "read output is not the expected output");
+ exit (1);
+ }
+ fclose (fp);
+ status = 0;
+ while (waitpid (child, &status, 0) != child)
+ ;
+ if (!WIFEXITED (status))
+ {
+ fprintf (stderr, "subprocess terminated with unexpected wait status %d\n", status);
+ exit (1);
+ }
+ exitstatus = WEXITSTATUS (status);
+ if (exitstatus != 0)
+ {
+ fprintf (stderr, "subprocess terminated with unexpected exit status %d\n", exitstatus);
+ exit (1);
+ }
+ return 0;
+}
diff --git a/tests/test-posix_spawn_file_actions_addfchdir.c b/tests/test-posix_spawn_file_actions_addfchdir.c
new file mode 100644
index 0000000..d7df690
--- /dev/null
+++ b/tests/test-posix_spawn_file_actions_addfchdir.c
@@ -0,0 +1,44 @@
+/* Test posix_spawn_file_actions_addfchdir() function.
+ Copyright (C) 2018-2019 Free Software Foundation, Inc.
+
+ 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 <https://www.gnu.org/licenses/>. */
+
+#include <config.h>
+
+#include <spawn.h>
+
+#include "signature.h"
+SIGNATURE_CHECK (posix_spawn_file_actions_addfchdir, int,
+ (posix_spawn_file_actions_t *, int));
+
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <unistd.h>
+
+#include "macros.h"
+
+int
+main (void)
+{
+ posix_spawn_file_actions_t actions;
+
+ ASSERT (posix_spawn_file_actions_init (&actions) == 0);
+
+ ASSERT (posix_spawn_file_actions_addfchdir (&actions, 3) == 0);
+
+ posix_spawn_file_actions_destroy (&actions);
+
+ return 0;
+}
--
2.7.4
[-- Attachment #5: 0004-posix_spawn_file_actions_addopen-Fix-possible-use-af.patch --]
[-- Type: text/x-patch, Size: 5111 bytes --]
From 765146c33361b46aa2c592e980b16069094c6000 Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Mon, 10 Jun 2019 16:50:04 +0200
Subject: [PATCH 4/5] posix_spawn_file_actions_addopen: Fix possible
use-after-free bug.
Reported at <https://sourceware.org/bugzilla/show_bug.cgi?id=17048>.
* lib/spawn_int.h (struct __spawn_action): Remove 'const' from path.
* lib/spawn_faction_addopen.c (posix_spawn_file_actions_addopen): Make
a copy of the path argument.
* lib/spawn_faction_destroy.c (posix_spawn_file_actions_destroy): Free
it.
---
ChangeLog | 10 ++++++++++
lib/spawn_faction_addopen.c | 47 +++++++++++++++++++++++++++++----------------
lib/spawn_faction_destroy.c | 29 +++++++++++++++++++++++++++-
lib/spawn_int.h | 2 +-
4 files changed, 69 insertions(+), 19 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 7bbf5fa..16f720d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,15 @@
2019-06-10 Bruno Haible <bruno@clisp.org>
+ posix_spawn_file_actions_addopen: Fix possible use-after-free bug.
+ Reported at <https://sourceware.org/bugzilla/show_bug.cgi?id=17048>.
+ * lib/spawn_int.h (struct __spawn_action): Remove 'const' from path.
+ * lib/spawn_faction_addopen.c (posix_spawn_file_actions_addopen): Make
+ a copy of the path argument.
+ * lib/spawn_faction_destroy.c (posix_spawn_file_actions_destroy): Free
+ it.
+
+2019-06-10 Bruno Haible <bruno@clisp.org>
+
posix_spawn_file_actions_addfchdir: Add tests.
* tests/test-posix_spawn_file_actions_addfchdir.c: New file.
* tests/test-posix_spawn5.c: New file.
diff --git a/lib/spawn_faction_addopen.c b/lib/spawn_faction_addopen.c
index 6b4422f..ab4f727 100644
--- a/lib/spawn_faction_addopen.c
+++ b/lib/spawn_faction_addopen.c
@@ -20,6 +20,8 @@
#include <spawn.h>
#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
#include <unistd.h>
#if !_LIBC
@@ -47,27 +49,38 @@ posix_spawn_file_actions_addopen (posix_spawn_file_actions_t *file_actions,
#if !REPLACE_POSIX_SPAWN
return posix_spawn_file_actions_addopen (file_actions, fd, path, oflag, mode);
#else
- /* Allocate more memory if needed. */
- if (file_actions->_used == file_actions->_allocated
- && __posix_spawn_file_actions_realloc (file_actions) != 0)
- /* This can only mean we ran out of memory. */
- return ENOMEM;
-
{
- struct __spawn_action *rec;
+ /* Copy PATH, because the caller may free it before calling posix_spawn()
+ or posix_spawnp(). */
+ char *path_copy = strdup (path);
+ if (path_copy == NULL)
+ return ENOMEM;
+
+ /* Allocate more memory if needed. */
+ if (file_actions->_used == file_actions->_allocated
+ && __posix_spawn_file_actions_realloc (file_actions) != 0)
+ {
+ /* This can only mean we ran out of memory. */
+ free (path_copy);
+ return ENOMEM;
+ }
+
+ {
+ struct __spawn_action *rec;
- /* Add the new value. */
- rec = &file_actions->_actions[file_actions->_used];
- rec->tag = spawn_do_open;
- rec->action.open_action.fd = fd;
- rec->action.open_action.path = path;
- rec->action.open_action.oflag = oflag;
- rec->action.open_action.mode = mode;
+ /* Add the new value. */
+ rec = &file_actions->_actions[file_actions->_used];
+ rec->tag = spawn_do_open;
+ rec->action.open_action.fd = fd;
+ rec->action.open_action.path = path_copy;
+ rec->action.open_action.oflag = oflag;
+ rec->action.open_action.mode = mode;
- /* Account for the new entry. */
- ++file_actions->_used;
+ /* Account for the new entry. */
+ ++file_actions->_used;
- return 0;
+ return 0;
+ }
}
#endif
}
diff --git a/lib/spawn_faction_destroy.c b/lib/spawn_faction_destroy.c
index 6d9ec80..0640da4 100644
--- a/lib/spawn_faction_destroy.c
+++ b/lib/spawn_faction_destroy.c
@@ -21,11 +21,38 @@
#include <stdlib.h>
+#if REPLACE_POSIX_SPAWN
+# include "spawn_int.h"
+#endif
+
/* Initialize data structure for file attribute for 'spawn' call. */
int
posix_spawn_file_actions_destroy (posix_spawn_file_actions_t *file_actions)
+#undef posix_spawn_file_actions_destroy
{
- /* Free the memory allocated. */
+#if !REPLACE_POSIX_SPAWN
+ return posix_spawn_file_actions_destroy (file_actions);
+#else
+ int i;
+
+ /* Free the paths in the open actions. */
+ for (i = 0; i < file_actions->_used; ++i)
+ {
+ struct __spawn_action *sa = &file_actions->_actions[i];
+ switch (sa->tag)
+ {
+ case spawn_do_open:
+ free (sa->action.open_action.path);
+ break;
+ default:
+ /* No cleanup required. */
+ break;
+ }
+ }
+
+ /* Free the array of actions. */
free (file_actions->_actions);
+
return 0;
+#endif
}
diff --git a/lib/spawn_int.h b/lib/spawn_int.h
index 584c1bb..08c477a 100644
--- a/lib/spawn_int.h
+++ b/lib/spawn_int.h
@@ -42,7 +42,7 @@ struct __spawn_action
struct
{
int fd;
- const char *path;
+ char *path;
int oflag;
mode_t mode;
} open_action;
--
2.7.4
[-- Attachment #6: 0005-posix_spawn_file_actions_addchdir-Fix-possible-use-a.patch --]
[-- Type: text/x-patch, Size: 4098 bytes --]
From b827d8a6fab0c25eaf0c59b94c5bbef00efeeae5 Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Mon, 10 Jun 2019 16:51:51 +0200
Subject: [PATCH 5/5] posix_spawn_file_actions_addchdir: Fix possible
use-after-free bug.
* lib/spawn_int.h (struct __spawn_action): Remove 'const' from path.
* lib/spawn_faction_addchdir.c (posix_spawn_file_actions_addchdir): Make
a copy of the path argument.
* lib/spawn_faction_destroy.c (posix_spawn_file_actions_destroy): Free
it.
---
ChangeLog | 9 +++++++++
lib/spawn_faction_addchdir.c | 41 +++++++++++++++++++++++++++--------------
lib/spawn_faction_destroy.c | 1 +
lib/spawn_int.h | 2 +-
4 files changed, 38 insertions(+), 15 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 16f720d..217779e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,14 @@
2019-06-10 Bruno Haible <bruno@clisp.org>
+ posix_spawn_file_actions_addchdir: Fix possible use-after-free bug.
+ * lib/spawn_int.h (struct __spawn_action): Remove 'const' from path.
+ * lib/spawn_faction_addchdir.c (posix_spawn_file_actions_addchdir): Make
+ a copy of the path argument.
+ * lib/spawn_faction_destroy.c (posix_spawn_file_actions_destroy): Free
+ it.
+
+2019-06-10 Bruno Haible <bruno@clisp.org>
+
posix_spawn_file_actions_addopen: Fix possible use-after-free bug.
Reported at <https://sourceware.org/bugzilla/show_bug.cgi?id=17048>.
* lib/spawn_int.h (struct __spawn_action): Remove 'const' from path.
diff --git a/lib/spawn_faction_addchdir.c b/lib/spawn_faction_addchdir.c
index b270e1f..925874c 100644
--- a/lib/spawn_faction_addchdir.c
+++ b/lib/spawn_faction_addchdir.c
@@ -19,6 +19,8 @@
#include <spawn.h>
#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
#if REPLACE_POSIX_SPAWN
# include "spawn_int.h"
@@ -34,24 +36,35 @@ posix_spawn_file_actions_addchdir (posix_spawn_file_actions_t *file_actions,
#if !REPLACE_POSIX_SPAWN
return posix_spawn_file_actions_addchdir_np (file_actions, path);
#else
- /* Allocate more memory if needed. */
- if (file_actions->_used == file_actions->_allocated
- && __posix_spawn_file_actions_realloc (file_actions) != 0)
- /* This can only mean we ran out of memory. */
- return ENOMEM;
-
{
- struct __spawn_action *rec;
+ /* Copy PATH, because the caller may free it before calling posix_spawn()
+ or posix_spawnp(). */
+ char *path_copy = strdup (path);
+ if (path_copy == NULL)
+ return ENOMEM;
+
+ /* Allocate more memory if needed. */
+ if (file_actions->_used == file_actions->_allocated
+ && __posix_spawn_file_actions_realloc (file_actions) != 0)
+ {
+ /* This can only mean we ran out of memory. */
+ free (path_copy);
+ return ENOMEM;
+ }
+
+ {
+ struct __spawn_action *rec;
- /* Add the new value. */
- rec = &file_actions->_actions[file_actions->_used];
- rec->tag = spawn_do_chdir;
- rec->action.chdir_action.path = path;
+ /* Add the new value. */
+ rec = &file_actions->_actions[file_actions->_used];
+ rec->tag = spawn_do_chdir;
+ rec->action.chdir_action.path = path_copy;
- /* Account for the new entry. */
- ++file_actions->_used;
+ /* Account for the new entry. */
+ ++file_actions->_used;
- return 0;
+ return 0;
+ }
}
#endif
}
diff --git a/lib/spawn_faction_destroy.c b/lib/spawn_faction_destroy.c
index 0640da4..d7156a0 100644
--- a/lib/spawn_faction_destroy.c
+++ b/lib/spawn_faction_destroy.c
@@ -42,6 +42,7 @@ posix_spawn_file_actions_destroy (posix_spawn_file_actions_t *file_actions)
switch (sa->tag)
{
case spawn_do_open:
+ case spawn_do_chdir:
free (sa->action.open_action.path);
break;
default:
diff --git a/lib/spawn_int.h b/lib/spawn_int.h
index 08c477a..bcf8bbf 100644
--- a/lib/spawn_int.h
+++ b/lib/spawn_int.h
@@ -48,7 +48,7 @@ struct __spawn_action
} open_action;
struct
{
- const char *path;
+ char *path;
} chdir_action;
struct
{
--
2.7.4
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2019-06-10 15:29 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-06-10 15:29 posix_spawn fixes Bruno Haible
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).