diff options
-rw-r--r-- | ChangeLog.txt | 3 | ||||
-rw-r--r-- | ports/unix/guts/popen.c | 20 | ||||
-rw-r--r-- | ports/unix/pseudo_wrappers.c | 50 | ||||
-rw-r--r-- | ports/unix/wrapfuncs.in | 1 |
4 files changed, 74 insertions, 0 deletions
diff --git a/ChangeLog.txt b/ChangeLog.txt index c8c3b90..99d0213 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -1,3 +1,6 @@ +2012-03-26: + * (seebs) Add popen() call to set up environment. + 2012-02-06: * (seebs) Merge O_LARGEFILE into flags, not mode (thanks to Lei Liu at Wind River for the fix). 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 */ |