aboutsummaryrefslogtreecommitdiffstats
path: root/ports
diff options
context:
space:
mode:
authorPeter Seebach <peter.seebach@windriver.com>2012-03-26 15:53:10 -0500
committerPeter Seebach <peter.seebach@windriver.com>2012-03-27 10:20:52 -0500
commit29ee281563a27bdbfa00613f20a4aaa5ca2a42ae (patch)
tree800a4f80c72df596288e2a66fbb66a2dd64c0bb0 /ports
parent9461b2a88ba672c533a331f95dd5ba7eba683c77 (diff)
downloadpseudo-29ee281563a27bdbfa00613f20a4aaa5ca2a42ae.tar.gz
pseudo-29ee281563a27bdbfa00613f20a4aaa5ca2a42ae.tar.bz2
pseudo-29ee281563a27bdbfa00613f20a4aaa5ca2a42ae.zip
add popen() call
We weren't trapping popen(), so if environment variables were in an inconsistent state when popen() was called, Bad Things Happened. Add a popen() wrapper. Like a couple of other special cases, is applied even when pseudo is theoretically disabled, and that includes the antimagic case. (But we never use popen() so that's fine.)
Diffstat (limited to 'ports')
-rw-r--r--ports/unix/guts/popen.c20
-rw-r--r--ports/unix/pseudo_wrappers.c50
-rw-r--r--ports/unix/wrapfuncs.in1
3 files changed, 71 insertions, 0 deletions
diff --git a/ports/unix/guts/popen.c b/ports/unix/guts/popen.c
new file mode 100644
index 0000000..05f0f6a
--- /dev/null
+++ b/ports/unix/guts/popen.c
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2012 Wind River Systems; see
+ * guts/COPYRIGHT for information.
+ *
+ * FILE *popen(const char *command, const char *mode)
+ * FILE *rc = NULL;
+ */
+
+ /* on at least some systems, popen() calls fork and exec
+ * in ways that avoid our usual enforcement of the environment.
+ */
+ pseudo_setupenv();
+ if (pseudo_get_value("PSEUDO_UNLOAD"))
+ pseudo_dropenv();
+
+ rc = real_popen(command, mode);
+
+/* return rc;
+ * }
+ */
diff --git a/ports/unix/pseudo_wrappers.c b/ports/unix/pseudo_wrappers.c
new file mode 100644
index 0000000..dddb1ec
--- /dev/null
+++ b/ports/unix/pseudo_wrappers.c
@@ -0,0 +1,50 @@
+FILE *
+popen(const char *command, const char *mode) {
+ sigset_t saved;
+
+ FILE *rc = NULL;
+
+ if (!pseudo_check_wrappers() || !real_popen) {
+ /* rc was initialized to the "failure" value */
+ pseudo_enosys("popen");
+ return rc;
+ }
+
+ pseudo_debug(4, "called: popen\n");
+ pseudo_sigblock(&saved);
+ if (pseudo_getlock()) {
+ errno = EBUSY;
+ sigprocmask(SIG_SETMASK, &saved, NULL);
+ return NULL;
+ }
+
+ int save_errno;
+ /* exec*() use this to restore the sig mask */
+ pseudo_saved_sigmask = saved;
+ rc = wrap_popen(command, mode);
+
+ save_errno = errno;
+ pseudo_droplock();
+ sigprocmask(SIG_SETMASK, &saved, NULL);
+#if 0
+/* This can cause hangs on some recentish systems which use locale
+ * stuff for strerror...
+ */
+ pseudo_debug(4, "completed: popen (maybe: %s)\n", strerror(save_errno));
+#endif
+ pseudo_debug(4, "completed: popen (errno: %d)\n", save_errno);
+ errno = save_errno;
+ return rc;
+}
+
+static FILE *
+wrap_popen(const char *command, const char *mode) {
+ FILE *rc = NULL;
+
+
+
+#include "guts/popen.c"
+
+ return rc;
+}
+
diff --git a/ports/unix/wrapfuncs.in b/ports/unix/wrapfuncs.in
index 32250c4..775f38a 100644
--- a/ports/unix/wrapfuncs.in
+++ b/ports/unix/wrapfuncs.in
@@ -56,3 +56,4 @@ int unlinkat(int dirfd, const char *path, int rflags); /* flags=AT_SYMLINK_NOFOL
ssize_t readlink(const char *path, char *buf, size_t bufsiz); /* flags=AT_SYMLINK_NOFOLLOW */
ssize_t readlinkat(int dirfd, const char *path, char *buf, size_t bufsiz); /* flags=AT_SYMLINK_NOFOLLOW */
int system(const char *command);
+FILE *popen(const char *command, const char *mode); /* hand_wrapped=1 */