home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 4 / DATAFILE_PDCD4.iso / unix / unixlib36d / src / sys / c / exec < prev    next >
Text File  |  1994-03-08  |  9KB  |  464 lines

  1. static char sccs_id[] = "@(#) exec.c 3.0 " __DATE__ " HJR";
  2.  
  3. /* exec.c (c) Copyright 1990 H.Rogers */
  4.  
  5. #include <errno.h>
  6. #include <stdarg.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9.  
  10. #include "fcntl.h"
  11.  
  12. #include "sys/param.h"
  13. #include "sys/unix.h"
  14. #include "sys/syslib.h"
  15. #include "sys/debug.h"
  16.  
  17. static int
  18. __execl (char *name, va_list argp)
  19. {
  20.   char *argv[MAXCOMMANDLEN >> 2];
  21.   int i;
  22.  
  23.   for (i = 0; i < (MAXCOMMANDLEN >> 2) && (argv[i] = va_arg (argp, char *)); i++);
  24.   if (i >= (MAXCOMMANDLEN >> 2))
  25.     {
  26.       errno = E2BIG;
  27.       return (-1);
  28.     }
  29.   return (execve (name, argv, environ));
  30. }
  31.  
  32. int
  33. execl (char *name,...)
  34. {
  35.   va_list argp;
  36.   va_start (argp, name);
  37.   return (__execl (name, argp));
  38. }
  39.  
  40. int
  41. execle (char *name,...)
  42. {
  43.   va_list argp;
  44.   va_start (argp, name);
  45.   return (__execl (name, argp));
  46. }
  47.  
  48. int
  49. execlp (char *name,...)
  50. {
  51.   va_list argp;
  52.   va_start (argp, name);
  53.   return (__execl (name, argp));
  54. }
  55.  
  56. int
  57. execv (char *name, char **argv)
  58. {
  59.   return (execve (name, argv, environ));
  60. }
  61.  
  62. int
  63. execvp (char *name, char **argv)
  64. {
  65.   return (execve (name, argv, environ));
  66. }
  67.  
  68.  
  69. #define ushift(p,v) ((p) = __ushift(p,v))
  70. #define ushift2(p,v,t) ((p) = (t)__ushift((void *)p,v))
  71.  
  72. static void *
  73. __ushift (register void *p, register int v)
  74. {
  75.   register void *q = (char *) p + v;
  76.  
  77.   return (((char *) p >= __base && (char *) p < __break) ? q : p);
  78. }
  79.  
  80. #define dshift(p,v) ((p) = __dshift(p,v))
  81. #define dshift2(p,v,t) ((p) = (t)__dshift((void *)p,v))
  82.  
  83. static void *
  84. __dshift (register void *p, register int v)
  85. {
  86.   register void *q = (char *) p + v;
  87.  
  88.   return (((char *) q >= __base && (char *) q < __break) ? q : p);
  89. }
  90.  
  91. os_error *__exerr;
  92.  
  93. int
  94. execve (char *name, char **argv, char **envp)
  95. {
  96.   register struct proc *u = __u;
  97.   register int i, l;
  98.   register char *s1, *s2, *s3;
  99.   register struct env *e;
  100.   void (*__exec) (char *);
  101.   char cli[MAXCOMMANDLEN];
  102.  
  103. #ifdef DEBUG
  104.   __debug ("execve() (init)");
  105. #endif
  106.  
  107.   if (!name || !argv || !envp)
  108.     {
  109.       errno = EINVAL;
  110.       return (-1);
  111.     }
  112.  
  113.   if (*name != '*')
  114.     name = __uname (name, 0);
  115.  
  116. /* check MAXCOMMANDLEN */
  117.  
  118. #ifdef DEBUG
  119.   os_print ("checking MAXCOMMANDLEN\n\r");
  120. #endif
  121.  
  122.   l = strlen (name) + 1;
  123.   for (i = 0; argv[i] && l < MAXCOMMANDLEN; l += strlen (argv[i]) + 1, i++);
  124.   if (l >= MAXCOMMANDLEN)
  125.     {
  126.       errno = E2BIG;
  127.       return (-1);
  128.     }
  129.  
  130. /* shortcut if no parent */
  131.  
  132.   if (!(u->flag & __U_PPROC))
  133.     {
  134.       s2 = cli;
  135.       s3 = name;
  136. #ifdef DEBUG
  137.       os_print ("Taking a shortcut\n\r");
  138. #endif
  139.       if (*s3 != '*')
  140.     *s2++ = '/';
  141.       while (*s2++ = *s3++);
  142.       s2[-1] = ' ';
  143.       if (argv[0])
  144.     for (i = 1; s3 = argv[i]; i++)
  145.       {
  146.         while (*s2++ = *s3++);
  147.         s2[-1] = ' ';
  148.       }
  149.       s2[-1] = 0;
  150.       __reset ();
  151.  
  152.       if (strlen (cli) >= MAXPATHLEN)    /* We need to use DDE utils for this */
  153.     {
  154.       int r[10];
  155.       char *temp = strchr (cli, ' ');
  156. #ifdef DEBUG
  157.       os_print ("Shortcut requires DDE\n\r");
  158. #endif
  159.       if ((temp - cli) >= MAXPATHLEN)
  160.         {
  161.           errno = E2BIG;
  162.           return (-1);
  163.         }            /* still too long */
  164.       r[0] = strlen (temp + 1);
  165.       if (os_swi (0x42581, r))
  166.         {
  167.           errno = E2BIG;
  168.           return (-1);
  169.         }            /* no DDE utils */
  170.       r[0] = (int) temp + 1;
  171.       os_swi (0x42582, r);
  172.       *temp = '\0';
  173. #ifdef DEBUG
  174.       os_print ("Shortcut - DDE setup\n\r");
  175. #endif
  176.     }
  177.  
  178.       os_cli (cli);
  179.       {
  180.     int r[10];
  181.     r[0] = r[1] = r[2] = 0;
  182.     os_swi (0x11, r);
  183.       }
  184.     }
  185.  
  186. /* check for overlapping argv arrays */
  187. #ifdef DEBUG
  188.   os_print ("Doing it the long way\n\r");
  189. #endif
  190.  
  191.   l = argv - u->argv;
  192.   if (l < 0)
  193.     l = -l;
  194.  
  195.   if (l <= i)
  196.     {
  197.       errno = EINVAL;
  198.       return (-1);
  199.     }
  200.  
  201. /* check free memory */
  202.  
  203.   if (((unsigned int) __base & ~0xff) == 0x8000)
  204.     __exshift = ((char *) __stack - (char *) __break) - 512 - __exlen;
  205.   else
  206.     __exshift = 0;
  207.  
  208.   if (__exshift < MAXCOMMANDLEN)
  209.     {
  210.       errno = ENOMEM;
  211.       return (-1);
  212.     }
  213.  
  214. /* copy name into u->argb */
  215.  
  216.   s1 = u->argb;
  217.   s2 = cli;
  218.   s3 = name;
  219.   if (*s3 != '*')
  220.     *s2++ = '/';
  221.   while (*s1++ = *s2++ = *s3++);
  222.   s2[-1] = ' ';
  223.  
  224. /* write cli args, u->argv[] & u->argc */
  225.  
  226.   if (argv[0])
  227.     {
  228.       s3 = argv[0];
  229.       u->argv[0] = s1;
  230.       while (*s1++ = *s3++);
  231.       for (i = 1; s3 = argv[i]; i++)
  232.     {
  233.       u->argv[i] = s1;
  234.       while (*s1++ = *s2++ = *s3++);
  235.       s2[-1] = ' ';
  236.     }
  237.     }
  238.   else
  239.     {
  240.       i = 0;
  241.       *s1 = 0;
  242.     }
  243.  
  244.   u->argv[u->argc = i] = 0;
  245.  
  246. /* terminate cli */
  247.  
  248.   s2[-1] = 0;
  249.  
  250. #ifdef DEBUG
  251.   os_print ("cli set up : ");
  252.   os_print (cli);
  253.   os_print ("\n\r");
  254. #endif
  255.  
  256.   if (strlen (cli) >= MAXPATHLEN)    /* We need to use DDE utils for this */
  257.     {
  258.       int r[10];
  259.       char *temp = cli;
  260.       if (*temp == '*')
  261.     temp++;
  262.       while (*temp == ' ')
  263.     temp++;            /* command starts star, space - right pain */
  264.  
  265.       temp = strchr (temp, ' ');
  266. #ifdef DEBUG
  267.       os_print ("long way requires DDE : ");
  268.       os_print (cli);
  269.       os_print ("\n\r");
  270. #endif
  271.       if ((temp - cli) >= MAXPATHLEN)
  272.     {
  273.       errno = E2BIG;
  274.       return (-1);
  275.     }            /* still too long */
  276.       r[0] = strlen (temp + 1);
  277.       if (os_swi (0x42581, r))
  278.     {
  279.       errno = E2BIG;
  280.       return (-1);
  281.     }            /* no DDE utils */
  282.       r[0] = (int) temp + 1;
  283.       os_swi (0x42582, r);
  284.       *temp = '\0';
  285. #ifdef DEBUG
  286.       os_print ("DDE utils set up\n\r");
  287. #endif
  288.     }
  289.  
  290. #ifdef DEBUG
  291.   __debug ("execve() (argv)");
  292. #endif
  293.  
  294.   for (i = 0; i < MAXFD; i++)
  295.     if (u->file[i].oflag & O_EXECCL)
  296.       close (i);
  297.  
  298.   alarm (0);            /* just in case */
  299.  
  300.   u->flag &= ~__U_PPROC;
  301.  
  302. #ifdef DEBUG
  303.   __debug ("execve()");
  304. #endif
  305.  
  306. /* deinstall handlers */
  307.  
  308.   e = __Oenv;
  309.   for (i = 0; i < 13; i++)
  310.     __wrenv (i, e->h + i);
  311.  
  312. /* shift __u pointers if necessary */
  313.  
  314.   if (__exshift)
  315.     {
  316.       register int v = __exshift;
  317.       register struct proc *u = __u;
  318.  
  319.       for (i = 0; i < u->argc; i++)
  320.     ushift (u->argv[i], v);
  321.       ushift (u->argv, v);
  322.       ushift (u->argb, v);
  323.       for (i = 0; i < MAXFD; i++)
  324.     if (u->file[i].dup)
  325.       ushift (u->file[i].dup, v);
  326.       for (i = 0; i < MAXTTY; i++)
  327.     {
  328.       if (u->tty[i].out)
  329.         ushift2 (u->tty[i].out, v, int (*)(int));
  330.       if (u->tty[i].in)
  331.         ushift2 (u->tty[i].in, v, int (*)(void));
  332.       if (u->tty[i].scan)
  333.         ushift2 (u->tty[i].scan, v, int (*)(int));
  334.       if (u->tty[i].init)
  335.         ushift2 (u->tty[i].init, v, int (*)(void));
  336.       if (u->tty[i].flush)
  337.         ushift2 (u->tty[i].flush, v, int (*)(void));
  338.  
  339.       if (u->tty[i].del)
  340.         ushift (u->tty[i].del, v);
  341.       if (u->tty[i].buf)
  342.         ushift (u->tty[i].buf, v);
  343.       if (u->tty[i].ptr)
  344.         ushift (u->tty[i].ptr, v);
  345.     }
  346.       ushift (u->tty, v);
  347.  
  348.       __exec = (void (*)(char *)) ((char *) __break + __exshift);
  349.     }
  350.   else
  351.     __exec = __exptr;
  352.  
  353.   {
  354.     int r[10];
  355.     char *v[1];
  356.  
  357.     v[0] = (char *) __u + __exshift;
  358.     r[0] = (int) "UnixLib$env";
  359.     r[1] = (int) v;
  360.     r[2] = 4;
  361.     r[3] = 0;
  362.     r[4] = 1;
  363.     os_swi (0x24, r);
  364.   }
  365.  
  366. /* copy up m/code routine */
  367.  
  368.   if (__exshift)
  369.     memcpy ((char *) __exec, (char *) __exptr, __exlen);
  370.  
  371. /* call it... */
  372.  
  373. #ifdef DEBUG
  374.   os_print ("Final call : ");
  375.   os_print (cli);
  376.   os_print ("\n\r");
  377. #endif
  378.  
  379.   (*__exec) (cli);        /* HACK ME ?? */
  380.  
  381. /* never reached */
  382.  
  383.   return (0);
  384. }
  385.  
  386. void
  387. __exret (void)
  388. {
  389.   register struct env *e;
  390.   int i;
  391.  
  392. /* shift __u pointers back down */
  393.  
  394.   if (__exshift)
  395.     {
  396.       register int v = -__exshift;
  397.       register struct proc *u = __u;
  398.       register int i;
  399.  
  400.       dshift (u->tty, v);
  401.       for (i = 0; i < MAXTTY; i++)
  402.     {
  403.       if (u->tty[i].out)
  404.         dshift2 (u->tty[i].out, v, int (*)(int));
  405.       if (u->tty[i].in)
  406.         dshift2 (u->tty[i].in, v, int (*)(void));
  407.       if (u->tty[i].scan)
  408.         dshift2 (u->tty[i].scan, v, int (*)(int));
  409.       if (u->tty[i].init)
  410.         dshift2 (u->tty[i].init, v, int (*)(void));
  411.       if (u->tty[i].flush)
  412.         dshift2 (u->tty[i].flush, v, int (*)(void));
  413.  
  414.       if (u->tty[i].del)
  415.         dshift (u->tty[i].del, v);
  416.       if (u->tty[i].buf)
  417.         dshift (u->tty[i].buf, v);
  418.       if (u->tty[i].ptr)
  419.         dshift (u->tty[i].ptr, v);
  420.     }
  421.       for (i = 0; i < MAXFD; i++)
  422.     if (u->file[i].dup)
  423.       dshift (u->file[i].dup, v);
  424.       dshift (u->argb, v);
  425.       dshift (u->argv, v);
  426.       for (i = 0; i < u->argc; i++)
  427.     dshift (u->argv[i], v);
  428.     }
  429.  
  430. /* reinstall handlers */
  431.  
  432.   e = __Cenv;
  433.   for (i = 0; i < 13; i++)
  434.     __wrenv (i, e->h + i);
  435.  
  436.   {
  437.     int r[10];
  438.  
  439.