diff options
author | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2018-12-07 15:01:40 +0100 |
---|---|---|
committer | Florian Weimer <fweimer@redhat.com> | 2018-12-07 16:04:05 +0100 |
commit | 7c857b6f0db01e8d6876e601f0cbcd21d23e4dd5 (patch) | |
tree | bb1326962589e7c74416aa329bb68c56f7f195d2 /sysdeps/mach/hurd/spawni.c | |
parent | 3a3fb7557274108ea3dc5ac62333c808a6c171db (diff) | |
download | glibc-7c857b6f0db01e8d6876e601f0cbcd21d23e4dd5.tar.gz glibc-7c857b6f0db01e8d6876e601f0cbcd21d23e4dd5.tar.xz glibc-7c857b6f0db01e8d6876e601f0cbcd21d23e4dd5.zip |
hurd: Implement support for posix_spawn_file_actions_addfchdir_np
Diffstat (limited to 'sysdeps/mach/hurd/spawni.c')
-rw-r--r-- | sysdeps/mach/hurd/spawni.c | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/sysdeps/mach/hurd/spawni.c b/sysdeps/mach/hurd/spawni.c index b98e991d3b..16c927be24 100644 --- a/sysdeps/mach/hurd/spawni.c +++ b/sysdeps/mach/hurd/spawni.c @@ -259,6 +259,46 @@ __spawni (pid_t *pid, const char *file, return err; } + inline error_t child_lookup_under (file_t startdir, const char *file, + int oflag, mode_t mode, file_t *result) + { + error_t use_init_port (int which, error_t (*operate) (mach_port_t)) + { + return (which == INIT_PORT_CWDIR ? (*operate) (startdir) : + child_init_port (which, operate)); + } + + return __hurd_file_name_lookup (&use_init_port, &child_fd, 0, + file, oflag, mode, result); + } + auto error_t child_fchdir (int fd) + { + file_t new_ccwdir; + error_t err; + + if ((unsigned int)fd >= dtablesize + || dtable[fd] == MACH_PORT_NULL) + return EBADF; + + /* We look up "." to force ENOTDIR if it's not a directory and EACCES if + we don't have search permission. */ + if (dtable_cells[fd] != NULL) + err = HURD_PORT_USE (dtable_cells[fd], + ({ + child_lookup_under (port, ".", O_NOTRANS, 0, &new_ccwdir); + })); + else + err = child_lookup_under (dtable[fd], ".", O_NOTRANS, 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. */ @@ -553,6 +593,10 @@ __spawni (pid_t *pid, const char *file, case spawn_do_chdir: err = child_chdir (action->action.chdir_action.path); break; + + case spawn_do_fchdir: + err = child_fchdir (action->action.fchdir_action.fd); + break; } if (err) |