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

Reply via email to