diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc index 0a68671fb..158f1e5fb 100644 --- a/winsup/cygwin/path.cc +++ b/winsup/cygwin/path.cc @@ -850,7 +850,10 @@ path_conv::check (const char *src, unsigned opt, case virt_fdsymlink: /* Allow open/linkat to do the right thing. */ if (opt & PC_SYM_NOFOLLOW_PROCFD) - opt &= ~PC_SYM_FOLLOW; + { + opt &= ~PC_SYM_FOLLOW; + sym.path_flags |= PATH_RESOLVE_PROCFD; + } /*FALLTHRU*/ case virt_symlink: goto is_virtual_symlink; diff --git a/winsup/cygwin/path.h b/winsup/cygwin/path.h index 69da8fd93..af10321c5 100644 --- a/winsup/cygwin/path.h +++ b/winsup/cygwin/path.h @@ -69,6 +69,7 @@ enum path_types PATH_REP = _BIT ( 3), PATH_SYMLINK = _BIT ( 4), PATH_SOCKET = _BIT ( 5), + PATH_RESOLVE_PROCFD = _BIT ( 6), PATH_DONT_USE = _BIT (31) /* conversion to signed happens. */ }; @@ -192,6 +193,7 @@ class path_conv int iscygexec () const {return mount_flags & MOUNT_CYGWIN_EXEC;} int isopen () const {return path_flags & PATH_OPEN;} int isctty_capable () const {return path_flags & PATH_CTTY;} + int follow_fd_symlink () const {return path_flags & PATH_RESOLVE_PROCFD;} void set_cygexec (bool isset) { if (isset) diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index 9f43512b2..60f66a63b 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -1398,13 +1398,13 @@ open (const char *unix_path, int flags, ...) if (fd < 0) __leave; /* errno already set */ + int opt = PC_OPEN | PC_SYM_NOFOLLOW_PROCFD; + opt |= (flags & (O_NOFOLLOW | O_EXCL)) ? PC_SYM_NOFOLLOW + : PC_SYM_FOLLOW; /* This is a temporary kludge until all utilities can catch up with a change in behavior that implements linux functionality: opening a tty should not automatically cause it to become the controlling tty for the process. */ - int opt = PC_OPEN | PC_SYM_NOFOLLOW_PROCFD; - opt |= (flags & (O_NOFOLLOW | O_EXCL)) ? PC_SYM_NOFOLLOW - : PC_SYM_FOLLOW; if (!(flags & O_NOCTTY) && fd > 2 && myself->ctty != -2) { flags |= O_NOCTTY; @@ -1472,7 +1472,7 @@ open (const char *unix_path, int flags, ...) fh = fh_file; } - if (fh->dev () == FH_PROCESSFD) + if (fh->dev () == FH_PROCESSFD && fh->pc.follow_fd_symlink ()) { /* Reopen file by descriptor */ fh_file = fh->fd_reopen (flags);