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 */
