diff options
Diffstat (limited to 'hurd/hurdexec.c')
-rw-r--r-- | hurd/hurdexec.c | 46 |
1 files changed, 39 insertions, 7 deletions
diff --git a/hurd/hurdexec.c b/hurd/hurdexec.c index 5b27f18..546cc69 100644 --- a/hurd/hurdexec.c +++ b/hurd/hurdexec.c @@ -65,12 +65,16 @@ _hurd_exec_paths (task_t task, file_t file, _hurd_port_free (&_hurd_ports[i], &ulink_ports[i], ports[i]); } file_t *dtable; - unsigned int dtablesize, i; + unsigned int dtablesize, i, j; struct hurd_port **dtable_cells; struct hurd_userlink *ulink_dtable; struct hurd_sigstate *ss; mach_port_t *please_dealloc, *pdp; int reauth = 0; + mach_port_t *portnames = NULL; + mach_msg_type_number_t nportnames = 0; + mach_port_type_t *porttypes = NULL; + mach_msg_type_number_t nporttypes = 0; /* XXX needs to be hurdmalloc XXX */ if (argv == NULL) @@ -361,6 +365,15 @@ retry: if (pdp) { + /* Get all ports that we may not know about and we should thus destroy. */ + /* XXX need to disable other threads to be safe. */ + if (err = __mach_port_names (__mach_task_self (), + &portnames, &nportnames, + &porttypes, &nporttypes)) + return err; + if (nportnames != nporttypes) + return EGRATUITOUS; + /* Request the exec server to deallocate some ports from us if the exec succeeds. The init ports and descriptor ports will arrive in the new program's exec_startup message. If we @@ -370,9 +383,30 @@ retry: exec call. */ for (i = 0; i < _hurd_nports; ++i) - *pdp++ = ports[i]; + { + *pdp++ = ports[i]; + for (j = 0; j < nportnames; j++) + if (portnames[j] == ports[i]) + portnames[j] = MACH_PORT_NULL; + } for (i = 0; i < dtablesize; ++i) - *pdp++ = dtable[i]; + { + *pdp++ = dtable[i]; + for (j = 0; j < nportnames; j++) + if (portnames[j] == dtable[i]) + portnames[j] = MACH_PORT_NULL; + } + + /* Pack ports to be destroyed together. */ + for (i = 0, j = 0; i < nportnames; i++) + { + if (portnames[i] == MACH_PORT_NULL) + continue; + if (j != i) + portnames[j] = portnames[i]; + j++; + } + nportnames = j; } flags = 0; @@ -393,8 +427,7 @@ retry: _hurd_nports, ints, INIT_INT_MAX, please_dealloc, pdp - please_dealloc, - &_hurd_msgport, - task == __mach_task_self () ? 1 : 0); + portnames, nportnames); /* Fall back for backwards compatibility. This can just be removed when __file_exec goes away. */ if (err == MIG_BAD_ID) @@ -404,8 +437,7 @@ retry: ports, MACH_MSG_TYPE_COPY_SEND, _hurd_nports, ints, INIT_INT_MAX, please_dealloc, pdp - please_dealloc, - &_hurd_msgport, - task == __mach_task_self () ? 1 : 0); + portnames, nportnames); } /* Release references to the standard ports. */ |