Logo Search packages:      
Sourcecode: ksh version File versions  Download package

execve3d.c

/***********************************************************************
*                                                                      *
*               This software is part of the ast package               *
*          Copyright (c) 1989-2007 AT&T Intellectual Property          *
*                      and is licensed under the                       *
*                  Common Public License, Version 1.0                  *
*                    by AT&T Intellectual Property                     *
*                                                                      *
*                A copy of the License is available at                 *
*            http://www.opensource.org/licenses/cpl1.0.txt             *
*         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         *
*                                                                      *
*              Information and Software Systems Research               *
*                            AT&T Research                             *
*                           Florham Park NJ                            *
*                                                                      *
*                 Glenn Fowler <gsf@research.att.com>                  *
*                  David Korn <dgk@research.att.com>                   *
*                   Eduardo Krell <ekrell@adexus.cl>                   *
*                                                                      *
***********************************************************************/
#pragma prototyped

#include "3d.h"

#if _hdr_alloca

#include <alloca.h>

#else

void
fix(void)
{
      if (state.brk.beg)
      {
            ssize_t     n;

            if (state.brk.end && (n = state.brk.end - state.brk.beg) > 0)
            {
                  memset(state.brk.beg, 0, n);
                  if ((char*)sbrk(0) == state.brk.end)
                        sbrk(-n);
            }
            state.brk.beg = state.brk.end = 0;
      }
}

#endif

int
execve3d(const char* path, char* const* aargv, char* const* aarge)
{
      char**            argv = (char**)aargv;
      char**            arge = (char**)aarge;
      register char*    sp;
      register char*    ep;
      register int      size;
      register int      argn = 0;
      int         n;
      char*       tp;
      char        buf[PATH_MAX];
#if FS
      Mount_t*    mp;
#endif

      if (!(sp = pathreal(path, 0, NiL)))
            return(-1);
      if (state.safe && !state.path.level)
      {
            errno = EPERM;
            return(-1);
      }
      if (*sp == '/')
      {
#if HUH920211 /* mh corrupts static state strings */
            if (streq(sp, state.binsh)) sp = state.shell;
#else
            if (streq(sp, "/bin/sh")) sp = state.shell;
#endif
      }
      else if (!state.in_2d && --sp > state.path.name) *--sp = '.';
      sp = strncpy(buf, sp, sizeof(buf));
      if (state.level)
      {
            /*
             * make sure dot is set correctly if not top level
             */

            pathreal(state.pwd, 0, NiL);
      }
      if (arge == state.env + 1) arge--;
      else
      {
            register char**   op = arge;

            /*
             * compute size of environment pointers
             */

            while (*op++) argn++;
            argn += 2;
            argn *= sizeof(char*);
      }
      size = mapdump(NiL, NiL, MAP_EXEC);
      n = size + argn + 10;
      n = roundof(n, 32);
#if _hdr_alloca
      state.brk.beg = (char*)alloca(n);
#else
      state.brk.beg = (char*)sbrk(n);
      state.brk.end = (char*)sbrk(0);
#endif
      ep = state.brk.beg + argn + 10 - sizeof(var_3d) + 1;
      tp = strcopy(ep, var_3d);
      size = mapdump(NiL, tp, MAP_EXEC);
      if (!keep(tp, size, 1))
            reclaim();
      else
      {
            if (argn)
            {
                  register char**   op = arge;
                  register char**   np;

                  arge = (char**)state.brk.beg;
                  np = arge + 1;
                  while (*np++ = *op++);
            }
            arge[0] = ep;
      }
#if FS
      for (mp = state.global; mp; mp = mp->global)
      {
            if (fssys(mp, MSG_exec))
                  fscall(mp, MSG_exec, 0, sp, argv, arge);
            if (fssys(mp, MSG_close))
            {
                  register File_t*  fp;

                  for (fp = state.file; fp <= state.file + state.open; fp++)
                        if ((fp->flags & FILE_OPEN) && ((fp->flags & FILE_CLOEXEC) || (size = FCNTL(fp - state.file, F_GETFD, NiL)) >= 0 && (size & FD_CLOEXEC)) && !FSTAT(fp - state.file, &state.path.st))
                              fscall(mp, MSG_close, 0, fp - state.file, state.path.st.st_mtime);
            }
      }
#endif
      EXECVE(sp, argv, arge);
      reclaim();
      return(-1);
}

Generated by  Doxygen 1.6.0   Back to index