Index: head/sys/compat/linux/linux_fork.c =================================================================== --- head/sys/compat/linux/linux_fork.c +++ head/sys/compat/linux/linux_fork.c @@ -131,12 +131,13 @@ linux_clone_proc(struct thread *td, struct linux_clone_args *args) { struct fork_req fr; - int error, ff = RFPROC | RFSTOPPED; + int error, ff = RFPROC | RFSTOPPED, f2; struct proc *p2; struct thread *td2; int exit_signal; struct linux_emuldata *em; + f2 = 0; exit_signal = args->flags & 0x000000ff; if (LINUX_SIG_VALID(exit_signal)) { exit_signal = linux_to_bsd_signal(exit_signal); @@ -147,14 +148,14 @@ ff |= RFMEM; if (args->flags & LINUX_CLONE_SIGHAND) ff |= RFSIGSHARE; - /* - * XXX: In Linux, sharing of fs info (chroot/cwd/umask) - * and open files is independent. In FreeBSD, its in one - * structure but in reality it does not cause any problems - * because both of these flags are usually set together. - */ - if (!(args->flags & (LINUX_CLONE_FILES | LINUX_CLONE_FS))) + if (args->flags & LINUX_CLONE_FILES) { + if (!(args->flags & LINUX_CLONE_FS)) + f2 |= FR2_SHARE_PATHS; + } else { ff |= RFFDG; + if (args->flags & LINUX_CLONE_FS) + f2 |= FR2_SHARE_PATHS; + } if (args->flags & LINUX_CLONE_PARENT_SETTID) if (args->parent_tidptr == NULL) @@ -165,6 +166,7 @@ bzero(&fr, sizeof(fr)); fr.fr_flags = ff; + fr.fr_flags2 = f2; fr.fr_procp = &p2; error = fork1(td, &fr); if (error) Index: head/sys/kern/kern_fork.c =================================================================== --- head/sys/kern/kern_fork.c +++ head/sys/kern/kern_fork.c @@ -414,11 +414,17 @@ fd = fdinit(p1->p_fd, false, NULL); fdtol = NULL; } else if (fr->fr_flags & RFFDG) { - pd = pdcopy(p1->p_pd); + if (fr->fr_flags2 & FR2_SHARE_PATHS) + pd = pdshare(p1->p_pd); + else + pd = pdcopy(p1->p_pd); fd = fdcopy(p1->p_fd); fdtol = NULL; } else { - pd = pdshare(p1->p_pd); + if (fr->fr_flags2 & FR2_SHARE_PATHS) + pd = pdcopy(p1->p_pd); + else + pd = pdshare(p1->p_pd); fd = fdshare(p1->p_fd); if (p1->p_fdtol == NULL) p1->p_fdtol = filedesc_to_leader_alloc(NULL, NULL, Index: head/sys/sys/proc.h =================================================================== --- head/sys/sys/proc.h +++ head/sys/sys/proc.h @@ -1017,7 +1017,8 @@ int fr_pd_flags; struct filecaps *fr_pd_fcaps; int fr_flags2; -#define FR2_DROPSIG_CAUGHT 0x00001 /* Drop caught non-DFL signals */ +#define FR2_DROPSIG_CAUGHT 0x00000001 /* Drop caught non-DFL signals */ +#define FR2_SHARE_PATHS 0x00000002 /* Invert sense of RFFDG for paths */ }; /*