Fix typos; move stray paragraph to Feature Test Macros.
[glibc/history.git] / sysdeps / mach / hurd / execve.c
blobd7e380c37e9b662d24ccf52586b5cccdaf4aebc0
1 /* Copyright (C) 1991, 1992 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
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.
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.
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. */
19 #include <ansidecl.h>
20 #include <errno.h>
21 #include <stddef.h>
22 #include <unistd.h>
23 #include <hurd.h>
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[])
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 file_t *dtable;
38 int dtablesize;
39 int i;
40 char *const *p;
41 task_t task;
42 int flags;
43 struct _hurd_sigstate *ss;
45 file = __hurd_path_lookup (path, FS_LOOKUP_EXECUTE, 0);
46 if (file == MACH_PORT_NULL)
47 return -1;
49 argslen = 0;
50 p = argv;
51 while (*p != NULL)
52 argslen += strlen (*p++) + 1;
53 args = __alloca (argslen);
54 ap = args;
55 for (p = argv; *p != NULL; ++p)
56 ap = __memccpy (ap, *p, '\0', UINT_MAX);
58 envlen = 0;
59 p = envp;
60 while (*p != NULL)
61 envlen += strlen (*p++) + 1;
62 env = __alloca (envlen);
63 ap = env;
64 for (p = envp; *p != NULL; ++p)
65 ap = __memccpy (ap, *p, '\0', UINT_MAX);
67 __mutex_lock (&_hurd_lock);
68 ports[INIT_PORT_CCDIR] = _hurd_ccdir;
69 ports[INIT_PORT_CWDIR] = _hurd_cwdir;
70 ports[INIT_PORT_CRDIR] = _hurd_crdir;
71 ports[INIT_PORT_AUTH] = _hurd_auth;
72 ports[INIT_PORT_PROC] = _hurd_proc;
73 ints[INIT_UMASK] = _hurd_umask;
74 ints[INIT_CTTY_FSTYPE] = _hurd_ctty_fstype;
75 ints[INIT_CTTY_FSID1] = _hurd_ctty_fsid.val[0];
76 ints[INIT_CTTY_FSID2] = _hurd_ctty_fsid.val[1];
77 ints[INIT_CTTY_FILEID] = _hurd_ctty_fileid;
79 ss = _hurd_thread_sigstate (__mach_thread_self ());
80 ints[INIT_SIGMASK] = ss->blocked;
81 ints[INIT_SIGIGN] = 0;
82 for (i = 1; i < NSIG; ++i)
83 if (ss->actions[i].sa_handler == SIG_IGN)
84 ints[INIT_SIGIGN] |= __sigmask (i);
86 if (ss->vforked)
88 /* This thread is vfork'd. */
89 task = MACH_PORT_NULL;
90 flags = FS_EXEC_NEWTASK;
92 else
94 task = __mach_task_self ();
95 flags = 0;
98 __mutex_lock (&_hurd_dtable_lock);
99 if (_hurd_dtable.d != NULL)
101 dtablesize = _hurd_dtable.size;
102 dtable = __alloca (dtablesize * sizeof (file_t));
103 for (i = 0; i < dtablesize; ++i)
104 if (_hurd_dtable.d[i].flags & FD_CLOEXEC)
105 dtable[i] = MACH_PORT_NULL;
106 else
107 dtable[i] = _hurd_dtable.d[i].server;
109 else
111 dtable = _hurd_init_dtable;
112 dtablesize = _hurd_init_dtablesize;
115 err = __file_exec (file, task,
116 args, argslen, env, envlen,
117 dtable, dtablesize,
118 ints, INIT_INT_MAX,
119 ports, INIT_PORT_MAX,
120 flags);
121 /* We must hold the dtable lock while doing the file_exec to avoid
122 the dtable entries being deallocated before we send them. */
123 __mutex_unlock (&_hurd_dtable_lock);
124 if (err)
125 return __hurd_fail (err);
127 if (ss->vforked)
128 longjmp (ss->vfork_saved.continuation, 1);
130 __mutex_unlock (&ss->lock);
132 /* That's interesting. */
133 return 0;