home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / gnu / glibc-1.06 / sysdeps / mach / hurd / __execve.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-04-26  |  6.0 KB  |  223 lines

  1. /* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc.
  2. This file is part of the GNU C Library.
  3.  
  4. The GNU C Library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Library General Public License as
  6. published by the Free Software Foundation; either version 2 of the
  7. License, or (at your option) any later version.
  8.  
  9. The GNU C Library is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  12. Library General Public License for more details.
  13.  
  14. You should have received a copy of the GNU Library General Public
  15. License along with the GNU C Library; see the file COPYING.LIB.  If
  16. not, write to the Free Software Foundation, Inc., 675 Mass Ave,
  17. Cambridge, MA 02139, USA.  */
  18.  
  19. #include <ansidecl.h>
  20. #include <errno.h>
  21. #include <stddef.h>
  22. #include <unistd.h>
  23. #include <hurd.h>
  24.  
  25. /* Replace the current process, executing PATH with arguments ARGV and
  26.    environment ENVP.  ARGV and ENVP are terminated by NULL pointers.  */
  27. int
  28. DEFUN(__execve, (path, argv, envp),
  29.       CONST char *path AND char *CONST argv[] AND char *CONST envp[])
  30. {
  31.   error_t err;
  32.   file_t file;
  33.   char *args, *env, *ap;
  34.   size_t argslen, envlen;
  35.   int ints[INIT_INT_MAX];
  36.   mach_port_t ports[INIT_PORT_MAX];
  37.   int dealloc_ports[INIT_PORT_MAX];
  38.   struct _hurd_port *port_cells[INIT_PORT_MAX];
  39.   file_t *dtable;
  40.   int dtablesize;
  41.   struct _hurd_port *dtable_cells;
  42.   int *dealloc_dtable;
  43.   int i;
  44.   char *const *p;
  45.   task_t task;
  46.   int flags;
  47.   struct _hurd_sigstate *ss;
  48.  
  49.   /* Get a port to the file we want to execute.  */
  50.   file = __path_lookup (path, FS_LOOKUP_EXECUTE, 0);
  51.   if (file == MACH_PORT_NULL)
  52.     return -1;
  53.  
  54.   /* Pack the arguments into an array with nulls separating the elements.  */
  55.   argslen = 0;
  56.   p = argv;
  57.   while (*p != NULL)
  58.     argslen += strlen (*p++) + 1;
  59.   args = __alloca (argslen);
  60.   ap = args;
  61.   for (p = argv; *p != NULL; ++p)
  62.     ap = __memccpy (ap, *p, '\0', ULONG_MAX);
  63.  
  64.   /* Pack the environment into an array with nulls separating the elements.  */
  65.   envlen = 0;
  66.   p = envp;
  67.   while (*p != NULL)
  68.     envlen += strlen (*p++) + 1;
  69.   env = __alloca (envlen);
  70.   ap = env;
  71.   for (p = envp; *p != NULL; ++p)
  72.     ap = __memccpy (ap, *p, '\0', ULONG_MAX);
  73.  
  74.   /* Load up the ports to give to the new program.  */
  75. #define    port(idx, cell)                                  \
  76.       case idx:                                      \
  77.     port_cells[i] = &cell;                              \
  78.     ports[i] = _hurd_port_get (&cell, &dealloc_ports[i]);              \
  79.     break
  80.   for (i = 0; i < INIT_PORT_MAX; ++i)
  81.     switch (i)
  82.       {
  83.     port (INIT_PORT_CCDIR, _hurd_ccdir);
  84.     port (INIT_PORT_CWDIR, _hurd_cwdir);
  85.     port (INIT_PORT_CRDIR, _hurd_crdir);
  86.     port (INIT_PORT_AUTH, _hurd_auth);
  87.     port (INIT_PORT_PROC, _hurd_proc);
  88.       default:
  89.     port_cells[i] = NULL;
  90.     break;
  91.       }
  92.  
  93.   /* Load up the ints to give the new program.  */
  94.   for (i = 0; i < INIT_INT_MAX; ++i)
  95.     switch (i)
  96.       {
  97.       case INIT_UMASK:
  98.     ints[i] = _hurd_umask;
  99.     break;
  100.       case INIT_CTTY_FSTYPE:
  101.     ints[i] = _hurd_ctty_fstype;
  102.     break;
  103.       case INIT_CTTY_FSID1:
  104.     ints[i] = _hurd_ctty_fsid.val[0];
  105.     break;
  106.       case INIT_CTTY_FSID2:
  107.     ints[i] = _hurd_ctty_fsid.val[1];
  108.     break;
  109.       case INIT_CTTY_FILEID:
  110.     ints[i] = _hurd_ctty_fileid;
  111.     break;
  112.  
  113.       case INIT_SIGMASK:
  114.       case INIT_SIGIGN:
  115.     break;
  116.  
  117.       default:
  118.     ints[i] = 0;
  119.       }
  120.  
  121.   ss = _hurd_thread_sigstate (__mach_thread_self ());
  122.   ints[INIT_SIGMASK] = ss->blocked;
  123.   ints[INIT_SIGPENDING] = ss->pending;
  124.   ints[INIT_SIGIGN] = 0;
  125.   for (i = 1; i < NSIG; ++i)
  126.     if (ss->actions[i].sa_handler == SIG_IGN)
  127.       ints[INIT_SIGIGN] |= __sigmask (i);
  128.  
  129.   /* We hold the sigstate lock until the exec has failed so that no signal
  130.      can arrive between when we pack the blocked and ignored signals, and
  131.      when the exec actually happens.  A signal handler could change what
  132.      signals are blocked and ignored.  Either the change will be reflected
  133.      in the exec, or the signal will never be delivered.  */
  134.  
  135. #if 0
  136.   if (ss->vforked)
  137.     {
  138.       /* This thread is vfork'd.  */
  139.       task = MACH_PORT_NULL;
  140.       flags = EXEC_NEWTASK;
  141.     }
  142.   else
  143. #endif
  144.     {
  145.       task = __mach_task_self ();
  146.       flags = 0;
  147.     }
  148.   
  149.   /* Pack up the descriptor table to give the new program.  */
  150.   __mutex_lock (&_hurd_dtable_lock);
  151.   if (_hurd_dtable.d != NULL)
  152.     {
  153.       dtablesize = _hurd_dtable.size;
  154.       dtable = __alloca (dtablesize * sizeof (dtable[0]));
  155.       dealloc_dtable = __alloca (dtablesize * sizeof (dealloc_dtable[0]));
  156.       dtable_cells = __alloca (dtablesize * sizeof (dealloc_cells[0]));
  157.       for (i = 0; i < dtablesize; ++i)
  158.     {
  159.       struct _hurd_fd *const = &_hurd_dtable.d[i];
  160.       __spin_lock (&d->port.lock);
  161.       if (d->flags & FD_CLOEXEC)
  162.         {
  163.           dtable[i] = MACH_PORT_NULL;
  164.           __spin_unlock (&d->port.lock);
  165.         }
  166.       else
  167.         {
  168.           /* If this is a descriptor to our controlling tty,
  169.          we want to give the normal port, not the foreground port.  */
  170.           dtable[i] = _hurd_port_get (&d->ctty, &dealloc_dtable[i]);
  171.           if (dtable[i] == MACH_PORT_NULL)
  172.         {
  173.           dtable[i] = _hurd_port_locked_get (&d->port,
  174.                              &dealloc_dtable[i]);
  175.           dtable_cells[i] = &d->port;
  176.         }
  177.           else
  178.         {
  179.           __spin_unlock (&d->port.lock);
  180.           dtable_cells[i] = &d->ctty;
  181.         }
  182.         }
  183.     }
  184.     }
  185.   else
  186.     {
  187.       dtable = _hurd_init_dtable;
  188.       dtablesize = _hurd_init_dtablesize;
  189.       dealloc_dtable = NULL;
  190.       dealloc_cells = NULL;
  191.     }
  192.  
  193.   err = __file_exec (file, task,
  194.              args, argslen, env, envlen,
  195.              dtable, dtablesize,
  196.              ints, INIT_INT_MAX,
  197.              ports, INIT_PORT_MAX,
  198.              flags);
  199.  
  200.   /* Safe to let signals happen now.  */
  201.   __mutex_unlock (&ss->lock);
  202.  
  203.   for (i = 0; i < INIT_PORT_MAX; ++i)
  204.     if (port_cells[i] != NULL)
  205.       _hurd_port_free (ports_cells[i], ports[i], &dealloc_ports[i]);
  206.  
  207.   if (dealloc_dtable != NULL)
  208.     for (i = 0; i < dtablesize; ++i)
  209.       if (dtable[i] != MACH_PORT_NULL)
  210.     _hurd_port_free (dtable_cells[i], dtable[i], &dealloc_dtable[i]);
  211.  
  212. #if 0
  213.   if (ss->vforked)
  214.     longjmp (ss->vfork_saved.continuation, 1);
  215. #endif
  216.  
  217.   if (err)
  218.     return __hurd_fail (err);
  219.  
  220.   /* That's interesting.  */
  221.   return 0;
  222. }
  223.