[ksh93-integration-discuss] ksh93 and |libc::wordexp()|, try 2 (and SMF debugging rants) ...
Roland Mainz
roland.mainz at nrubsig.org
Tue Jun 6 18:20:29 PDT 2006
Hi!
----
Attached is a patch for B37 usr/src/lib/libc/ which switches
|libc::wordexp()| over to use ksh93 for it's tasks. The patch now works
with svc/inetd flawlessly (except that it spamms syslog() with debug
output from the patch and the WRDE_NOCMD mode via rksh doesn't work yet
(see
http://mail.opensolaris.org/pipermail/ksh93-integration-discuss/2006-June/000392.html
for a posible solution, right now the #ifdef'ed out part of the patch
does not work since calling "exec" for stdin/stdout/stderr redirection
is not allowed in "rksh" (="restricted") mode)).
Slightly offtopic (WARNING: Offensive language may be used below):
<rant>
I also like to COMPLAIN about the svc/SMF framework in Solaris. It made
services such as inetd a SERIOUS PAIN to debug. There is no longer an
effective way to insert a debugger in the chain like it was possible
with Solaris < 10 nor is it effectively possible to attach a debugger
later because something seems to prevent dbx/gdb from being able to
track the smf/inetd children. The whole situation seriously sucks and
yesterday (when I did the debugging) I was very close to wish that
someone gets fed to komodo dragons, alive and feet first (that he/she
can watch being eaten alive) ... xx@@@!!... ;-((
</rant>
----
Bye,
Roland
--
__ . . __
(o.\ \/ /.o) roland.mainz at nrubsig.org
\__\/\/__/ MPEG specialist, C&&JAVA&&Sun&&Unix programmer
/O /==\ O\ TEL +49 641 7950090
(;O/ \/ \O;)
-------------- next part --------------
Index: port/regex/wordexp.c
===================================================================
--- port/regex/wordexp.c (revision 269)
+++ port/regex/wordexp.c (working copy)
@@ -41,6 +41,7 @@
* wordexp, wordfree -- POSIX.2 D11.2 word expansion routines.
*
* Copyright 1985, 1992 by Mortice Kern Systems Inc. All rights reserved.
+ * Modified by Roland Mainz <roland.mainz at nrubsig.org> to support ksh93
*
*/
@@ -57,14 +58,16 @@
#include <wordexp.h>
#include <stdio.h>
#include <errno.h>
+#if 1
+#include <syslog.h>
+#endif
#define INITIAL 8 /* initial pathv allocation */
#define BUFSZ 256 /* allocation unit of the line buffer */
-static int append(wordexp_t *, char *);
+/* Local prototypes */
+static int append(wordexp_t *, char *);
-extern int __xpg4; /* defined in _xpg4.c; 0 if not xpg4-compiled program */
-
/*
* Do word expansion.
* We just pass our arguments to shell with -E option. Note that the
@@ -74,25 +77,18 @@
int
wordexp(const char *word, wordexp_t *wp, int flags)
{
- static char options[9] = "-";
- static char *args[4];
- const char *path;
+ char *args[10];
wordexp_t wptmp;
size_t si;
int i;
pid_t pid;
- char *line, *eob, *cp; /* word from shell */
+ char *line, *eob, *cp; /* word from shell */
int rv = WRDE_ERRNO;
int status;
- int pv[2]; /* pipe from shell stdout */
- FILE *fp; /* pipe read stream */
- char *optendp = options+1;
+ int pv[2]; /* pipe from shell stdout */
+ FILE *fp; /* pipe read stream */
int serrno, tmpalloc;
- char *wd = NULL;
- static const char *sun_path = "/bin/ksh";
- static const char *xpg4_path = "/usr/xpg4/bin/sh";
-
/*
* Do absolute minimum neccessary for the REUSE flag. Eventually
* want to be able to actually avoid excessive malloc calls.
@@ -138,34 +134,16 @@
}
/*
- * Turn flags into shell options
- */
- *optendp++ = (char)0x05; /* ksh -^E */
- if (flags & WRDE_UNDEF)
- *optendp++ = 'u';
- if (flags & WRDE_NOCMD)
- *optendp++ = 'N';
- *optendp = '\0';
-
- if (getenv("PWD") == NULL) {
- if ((wd = malloc(PATH_MAX + 4)) == NULL)
- goto cleanup;
- (void) strcpy(wd, "PWD=");
- if (getcwd(&wd[4], PATH_MAX) == NULL)
- (void) strcpy(&wd[4], "/");
- }
-
- /*
* Set up pipe from shell stdout to "fp" for us
*/
if (pipe(pv) < 0)
goto cleanup;
/*
- * Fork/exec shell with -E word
+ * Fork/exec shell
*/
- if ((pid = fork1()) == -1) {
+ if ((pid = fork()) == -1) {
serrno = errno;
(void) close(pv[0]);
(void) close(pv[1]);
@@ -173,32 +151,59 @@
goto cleanup;
}
- if (pid == 0) { /* child */
- if (wd != NULL) {
- /*
- * fork1 handler takes care of __environ_lock.
- * Thus we can safely call putenv().
- */
- (void) putenv(wd);
- }
+ if (pid == 0) { /* child */
+ char buff[120+strlen(word)]; /* Needs C99 */
+ int i;
+ const char *path;
(void) dup2(pv[1], 1);
(void) close(pv[0]);
(void) close(pv[1]);
+ if (flags & WRDE_NOCMD) {
+ /*
+ * Use restricted shell (rksh) here to put the word
+ * expansion into a "cage" which prevents users
+ * from executing external commands (outside those
+ * listed by ${PATH}).
+ */
+#if 0
+ path = "/usr/bin/rksh";
+#else
+ path = "/usr/bin/ksh93";
+#endif
+ putenv("PATH=/usr/lib/libc/libc_wordexp_commands");
+ }
+ else
+ {
+ path = "/usr/bin/ksh93";
+ }
+
+ i = 0;
+
+ buff[0] = '\0';
+ if (flags & WRDE_UNDEF)
+ strcat(buff, "set -o nounset ; ");
if ((flags & WRDE_SHOWERR) == 0) {
- int devnull;
- devnull = open("/dev/null", O_WRONLY);
- (void) dup2(devnull, 2);
- if (devnull != 2)
- (void) close(devnull);
+ /*
+ * The newline ('\n') is neccesary to make sure that
+ * the redirection to /dev/null is already active in
+ * the case the printf below contains a syntax
+ * error...
+ */
+ strcat(buff, "exec 2>/dev/null\n");
}
+ /* Squish stdin */
+ strcat(buff, "exec 0</dev/null\n");
+ sprintf(&buff[strlen(buff)], "print -f \"%%s\\000\" %s", word);
- path = __xpg4 ? xpg4_path : sun_path;
- args[0] = strrchr(path, '/') + 1;
- args[1] = options;
- args[2] = (char *)word;
- args[3] = NULL;
+#if 1
+ syslog(LOG_CRIT, "wordexp(): cmd='%s', buffer='%s'", path, buff);
+#endif
+ args[i++] = strrchr(path, '/') + 1;
+ args[i++] = "-c";
+ args[i++] = buff;
+ args[i++] = NULL;
(void) execv(path, args);
_exit(127);
@@ -206,7 +211,7 @@
(void) close(pv[1]);
- if ((fp = fdopen(pv[0], "rb")) == NULL) {
+ if ((fp = fdopen(pv[0], "r")) == NULL) {
serrno = errno;
(void) close(pv[0]);
errno = serrno;
@@ -268,8 +273,6 @@
wordfree(&wptmp);
}
- if (wd)
- free(wd);
/*
* Map ksh errors to wordexp() errors
*/
More information about the ksh93-integration-discuss
mailing list