mirror of
https://sourceware.org/git/glibc.git
synced 2024-12-03 22:53:37 +08:00
Hurd: Implement chdir support in posix_spawn
This fixes build-many-glibcs.py on i686-gnu. Thanks Florian Weimer for the initial version. * sysdeps/mach/hurd/spawni.c (__spawni): Add ccwdir port. Test and use it, free it if needed. (reauthenticate): Test and use ccwdir. (child_init_port): In non-resetids case, test and use ccwdir. (child_chdir): New nested function to set ccwdir.
This commit is contained in:
parent
1626a1cfcd
commit
434c34bd8e
@ -1,3 +1,11 @@
|
||||
2018-11-10 Samuel Thibault <samuel.thibault@ens-lyon.org>
|
||||
|
||||
* sysdeps/mach/hurd/spawni.c (__spawni): Add ccwdir port. Test and use
|
||||
it, free it if needed.
|
||||
(reauthenticate): Test and use ccwdir.
|
||||
(child_init_port): In non-resetids case, test and use ccwdir.
|
||||
(child_chdir): New nested function to set ccwdir.
|
||||
|
||||
2018-11-09 Martin Sebor <msebor@redhat.com>
|
||||
|
||||
* include/libc-symbols.h (__attribute_copy__): Define macro unless
|
||||
|
@ -113,6 +113,9 @@ __spawni (pid_t *pid, const char *file,
|
||||
struct hurd_userlink *ulink_dtable = NULL;
|
||||
struct hurd_sigstate *ss;
|
||||
|
||||
/* Child current working dir */
|
||||
file_t ccwdir = MACH_PORT_NULL;
|
||||
|
||||
/* For POSIX_SPAWN_RESETIDS, this reauthenticates our root/current
|
||||
directory ports with the new AUTH port. */
|
||||
file_t rcrdir = MACH_PORT_NULL, rcwdir = MACH_PORT_NULL;
|
||||
@ -123,16 +126,25 @@ __spawni (pid_t *pid, const char *file,
|
||||
if (*result != MACH_PORT_NULL)
|
||||
return 0;
|
||||
ref = __mach_reply_port ();
|
||||
err = HURD_PORT_USE
|
||||
(&_hurd_ports[which],
|
||||
({
|
||||
err = __io_reauthenticate (port, ref, MACH_MSG_TYPE_MAKE_SEND);
|
||||
if (!err)
|
||||
err = __auth_user_authenticate (auth,
|
||||
ref, MACH_MSG_TYPE_MAKE_SEND,
|
||||
result);
|
||||
err;
|
||||
}));
|
||||
if (which == INIT_PORT_CWDIR && ccwdir != MACH_PORT_NULL)
|
||||
{
|
||||
err = __io_reauthenticate (ccwdir, ref, MACH_MSG_TYPE_MAKE_SEND);
|
||||
if (!err)
|
||||
err = __auth_user_authenticate (auth,
|
||||
ref, MACH_MSG_TYPE_MAKE_SEND,
|
||||
result);
|
||||
}
|
||||
else
|
||||
err = HURD_PORT_USE
|
||||
(&_hurd_ports[which],
|
||||
({
|
||||
err = __io_reauthenticate (port, ref, MACH_MSG_TYPE_MAKE_SEND);
|
||||
if (!err)
|
||||
err = __auth_user_authenticate (auth,
|
||||
ref, MACH_MSG_TYPE_MAKE_SEND,
|
||||
result);
|
||||
err;
|
||||
}));
|
||||
__mach_port_destroy (__mach_task_self (), ref);
|
||||
return err;
|
||||
}
|
||||
@ -177,6 +189,14 @@ __spawni (pid_t *pid, const char *file,
|
||||
return (reauthenticate (INIT_PORT_CWDIR, &rcwdir)
|
||||
?: (*operate) (rcwdir));
|
||||
}
|
||||
else
|
||||
switch (which)
|
||||
{
|
||||
case INIT_PORT_CWDIR:
|
||||
if (ccwdir != MACH_PORT_NULL)
|
||||
return (*operate) (ccwdir);
|
||||
break;
|
||||
}
|
||||
assert (which != INIT_PORT_PROC);
|
||||
return _hurd_ports_use (which, operate);
|
||||
}
|
||||
@ -205,6 +225,40 @@ __spawni (pid_t *pid, const char *file,
|
||||
return __hurd_file_name_lookup (&child_init_port, &child_fd, 0,
|
||||
file, oflag, mode, result);
|
||||
}
|
||||
auto error_t child_chdir (const char *name)
|
||||
{
|
||||
file_t new_ccwdir;
|
||||
|
||||
/* Append trailing "/." to directory name to force ENOTDIR if
|
||||
it's not a directory and EACCES if we don't have search
|
||||
permission. */
|
||||
len = strlen (name);
|
||||
const char *lookup = name;
|
||||
if (len >= 2 && name[len - 2] == '/' && name[len - 1] == '.')
|
||||
lookup = name;
|
||||
else if (len == 0)
|
||||
/* Special-case empty file name according to POSIX. */
|
||||
return __hurd_fail (ENOENT);
|
||||
else
|
||||
{
|
||||
char *n = alloca (len + 3);
|
||||
memcpy (n, name, len);
|
||||
n[len] = '/';
|
||||
n[len + 1] = '.';
|
||||
n[len + 2] = '\0';
|
||||
lookup = n;
|
||||
}
|
||||
|
||||
error_t err = child_lookup (lookup, 0, 0, &new_ccwdir);
|
||||
if (!err)
|
||||
{
|
||||
if (ccwdir != MACH_PORT_NULL)
|
||||
__mach_port_deallocate (__mach_task_self (), ccwdir);
|
||||
ccwdir = new_ccwdir;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
/* Do this once. */
|
||||
@ -485,6 +539,10 @@ __spawni (pid_t *pid, const char *file,
|
||||
dtable_cells[fd] = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
case spawn_do_chdir:
|
||||
err = child_chdir (action->action.chdir_action.path);
|
||||
break;
|
||||
}
|
||||
|
||||
if (err)
|
||||
@ -708,6 +766,11 @@ __spawni (pid_t *pid, const char *file,
|
||||
ports[i] = rcwdir;
|
||||
continue;
|
||||
}
|
||||
if (ccwdir != MACH_PORT_NULL)
|
||||
{
|
||||
ports[i] = ccwdir;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
ports[i] = _hurd_port_get (&_hurd_ports[i], &ulink_ports[i]);
|
||||
@ -748,6 +811,8 @@ __spawni (pid_t *pid, const char *file,
|
||||
case INIT_PORT_CWDIR:
|
||||
if (flags & POSIX_SPAWN_RESETIDS)
|
||||
continue;
|
||||
if (ccwdir != MACH_PORT_NULL)
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
_hurd_port_free (&_hurd_ports[i], &ulink_ports[i], ports[i]);
|
||||
@ -773,6 +838,8 @@ __spawni (pid_t *pid, const char *file,
|
||||
}
|
||||
__mach_port_deallocate (__mach_task_self (), auth);
|
||||
__mach_port_deallocate (__mach_task_self (), proc);
|
||||
if (ccwdir != MACH_PORT_NULL)
|
||||
__mach_port_deallocate (__mach_task_self (), ccwdir);
|
||||
if (rcrdir != MACH_PORT_NULL)
|
||||
__mach_port_deallocate (__mach_task_self (), rcrdir);
|
||||
if (rcwdir != MACH_PORT_NULL)
|
||||
|
Loading…
Reference in New Issue
Block a user