diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc index 5dbbd4068..8a184a71b 100644 --- a/winsup/cygwin/fhandler.cc +++ b/winsup/cygwin/fhandler.cc @@ -1409,32 +1409,46 @@ fhandler_base::init (HANDLE f, DWORD a, mode_t bin) return 1; } +/* SRC_PID, if not zero, is the Windows pid of the source process. */ int -fhandler_base::dup (fhandler_base *child, int) +fhandler_base::dup (fhandler_base *child, int, DWORD src_pid) { debug_printf ("in fhandler_base dup"); + int ret = -1; HANDLE nh; + HANDLE src_proc = GetCurrentProcess (); + + if (src_pid && !(src_proc = OpenProcess (PROCESS_DUP_HANDLE, false, src_pid))) + { + debug_printf ("can't open source process %d, %E", src_pid); + __seterrno (); + goto out; + } if (!nohandle () && !archetype) { - if (!DuplicateHandle (GetCurrentProcess (), get_handle (), + if (!DuplicateHandle (src_proc, get_handle (), GetCurrentProcess (), &nh, 0, TRUE, DUPLICATE_SAME_ACCESS)) { debug_printf ("dup(%s) failed, handle %p, %E", get_name (), get_handle ()); __seterrno (); - return -1; + goto out; } VerifyHandle (nh); child->set_handle (nh); } - return 0; + ret = 0; +out: + if (src_proc && src_proc != GetCurrentProcess ()) + CloseHandle (src_proc); + return ret; } int -fhandler_base_overlapped::dup (fhandler_base *child, int flags) +fhandler_base_overlapped::dup (fhandler_base *child, int flags, DWORD) { int res = fhandler_base::dup (child, flags) || ((fhandler_base_overlapped *) child)->setup_overlapped (); diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 79fabeab7..542f15e2b 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -414,7 +414,7 @@ public: virtual off_t lseek (off_t offset, int whence); virtual int lock (int, struct flock *); virtual int mand_lock (int, struct flock *); - virtual int dup (fhandler_base *child, int flags); + virtual int dup (fhandler_base *child, int flags, DWORD src_pid = 0); virtual int fpathconf (int); virtual HANDLE mmap (caddr_t *addr, size_t len, int prot, @@ -672,7 +672,7 @@ class fhandler_socket_wsock: public fhandler_socket int fixup_before_fork_exec (DWORD); void fixup_after_fork (HANDLE); void fixup_after_exec (); - int dup (fhandler_base *child, int); + int dup (fhandler_base *child, int, DWORD = 0); #ifdef __INSIDE_CYGWIN_NET__ protected: @@ -823,7 +823,7 @@ class fhandler_socket_local: public fhandler_socket_wsock fhandler_socket_local (); ~fhandler_socket_local (); - int dup (fhandler_base *child, int); + int dup (fhandler_base *child, int, DWORD = 0); int socket (int af, int type, int protocol, int flags); int socketpair (int af, int type, int protocol, int flags, @@ -1118,7 +1118,7 @@ class fhandler_socket_unix : public fhandler_socket fhandler_socket_unix (); ~fhandler_socket_unix (); - int dup (fhandler_base *child, int); + int dup (fhandler_base *child, int, DWORD = 0); DWORD wait_pipe_thread (PUNICODE_STRING pipe_name); @@ -1244,7 +1244,7 @@ public: void fixup_after_exec (); int close (); - int dup (fhandler_base *child, int); + int dup (fhandler_base *child, int, DWORD = 0); void check_later (); static void __reg1 flush_all_async_io ();; @@ -1295,7 +1295,7 @@ public: select_record *select_except (select_stuff *); char *get_proc_fd_name (char *buf); int open (int flags, mode_t mode = 0); - int dup (fhandler_base *child, int); + int dup (fhandler_base *child, int, DWORD = 0); int ioctl (unsigned int cmd, void *); int __reg2 fstat (struct stat *buf); int __reg2 fstatvfs (struct statvfs *buf); @@ -1549,7 +1549,7 @@ public: off_t lseek (off_t offset, int whence); int close (); int fcntl (int cmd, intptr_t); - int dup (fhandler_base *child, int); + int dup (fhandler_base *child, int, DWORD = 0); bool isfifo () const { return true; } void set_close_on_exec (bool val); void __reg3 raw_read (void *ptr, size_t& ulen); @@ -1609,7 +1609,7 @@ class fhandler_dev_raw: public fhandler_base int __reg2 fstat (struct stat *buf); - int dup (fhandler_base *child, int); + int dup (fhandler_base *child, int, DWORD = 0); int ioctl (unsigned int cmd, void *buf); void fixup_after_fork (HANDLE); @@ -1670,7 +1670,7 @@ class fhandler_dev_floppy: public fhandler_dev_raw int open (int flags, mode_t mode = 0); int close (); - int dup (fhandler_base *child, int); + int dup (fhandler_base *child, int, DWORD = 0); void __reg3 raw_read (void *ptr, size_t& ulen); ssize_t __reg3 raw_write (const void *ptr, size_t ulen); off_t lseek (off_t offset, int whence); @@ -1721,7 +1721,7 @@ class fhandler_dev_tape: public fhandler_dev_raw virtual int __reg2 fstat (struct stat *buf); - virtual int dup (fhandler_base *child, int); + virtual int dup (fhandler_base *child, int, DWORD = 0); virtual void fixup_after_fork (HANDLE parent); virtual void set_close_on_exec (bool val); virtual int ioctl (unsigned int cmd, void *buf); @@ -1765,7 +1765,7 @@ class fhandler_disk_file: public fhandler_base int open (int flags, mode_t mode); int close (); int fcntl (int cmd, intptr_t); - int dup (fhandler_base *child, int); + int dup (fhandler_base *child, int, DWORD = 0); void fixup_after_fork (HANDLE parent); int mand_lock (int, struct flock *); int __reg2 fstat (struct stat *buf); @@ -2218,7 +2218,7 @@ private: int open (int flags, mode_t mode); void open_setup (int flags); - int dup (fhandler_base *, int); + int dup (fhandler_base *, int, DWORD = 0); void __reg3 read (void *ptr, size_t& len); ssize_t __stdcall write (const void *ptr, size_t len); @@ -2378,7 +2378,7 @@ class fhandler_pty_slave: public fhandler_pty_common int ioctl (unsigned int cmd, void *); int close (); void cleanup (); - int dup (fhandler_base *child, int); + int dup (fhandler_base *child, int, DWORD = 0); void fixup_after_fork (HANDLE parent); void fixup_after_exec (); @@ -2456,7 +2456,7 @@ public: bool hit_eof (); bool setup (); - int dup (fhandler_base *, int); + int dup (fhandler_base *, int, DWORD = 0); void fixup_after_fork (HANDLE parent); void fixup_after_exec (); int tcgetpgrp (); @@ -2601,7 +2601,7 @@ class fhandler_dev_clipboard: public fhandler_base off_t lseek (off_t offset, int whence); int close (); - int dup (fhandler_base *child, int); + int dup (fhandler_base *child, int, DWORD = 0); void fixup_after_exec (); size_t get_size () const { return sizeof *this; } @@ -2742,7 +2742,7 @@ class fhandler_virtual : public fhandler_base ssize_t __stdcall write (const void *ptr, size_t len); void __reg3 read (void *ptr, size_t& len); off_t lseek (off_t, int); - int dup (fhandler_base *child, int); + int dup (fhandler_base *child, int, DWORD = 0); int open (int flags, mode_t mode = 0); int close (); int __reg2 fstatvfs (struct statvfs *buf); @@ -2930,7 +2930,7 @@ class fhandler_registry: public fhandler_proc int __reg2 fstat (struct stat *buf); bool fill_filebuf (); int close (); - int dup (fhandler_base *child, int); + int dup (fhandler_base *child, int, DWORD = 0); size_t get_size () const { return sizeof *this; } @@ -3111,7 +3111,7 @@ class fhandler_timerfd : public fhandler_base int __reg2 fstat (struct stat *buf); void __reg3 read (void *ptr, size_t& len); ssize_t __stdcall write (const void *, size_t); - int dup (fhandler_base *child, int); + int dup (fhandler_base *child, int, DWORD = 0); int ioctl (unsigned int, void *); int close (); diff --git a/winsup/cygwin/fhandler_clipboard.cc b/winsup/cygwin/fhandler_clipboard.cc index ccdb295f3..868dd3694 100644 --- a/winsup/cygwin/fhandler_clipboard.cc +++ b/winsup/cygwin/fhandler_clipboard.cc @@ -48,7 +48,7 @@ fhandler_dev_clipboard::fhandler_dev_clipboard () */ int -fhandler_dev_clipboard::dup (fhandler_base * child, int flags) +fhandler_dev_clipboard::dup (fhandler_base * child, int flags, DWORD) { fhandler_dev_clipboard *fhc = (fhandler_dev_clipboard *) child; fhc->pos = fhc->msize = 0; diff --git a/winsup/cygwin/fhandler_console.cc b/winsup/cygwin/fhandler_console.cc index 41cac37e6..54fe3e549 100644 --- a/winsup/cygwin/fhandler_console.cc +++ b/winsup/cygwin/fhandler_console.cc @@ -1071,7 +1071,7 @@ fhandler_console::scroll_buffer_screen (int x1, int y1, int x2, int y2, } int -fhandler_console::dup (fhandler_base *child, int flags) +fhandler_console::dup (fhandler_base *child, int flags, DWORD) { /* See comments in fhandler_pty_slave::dup */ if (myself->ctty != -2) diff --git a/winsup/cygwin/fhandler_disk_file.cc b/winsup/cygwin/fhandler_disk_file.cc index 885b59161..3d3e8ef22 100644 --- a/winsup/cygwin/fhandler_disk_file.cc +++ b/winsup/cygwin/fhandler_disk_file.cc @@ -1435,16 +1435,24 @@ fhandler_disk_file::fcntl (int cmd, intptr_t arg) } int -fhandler_disk_file::dup (fhandler_base *child, int flags) +fhandler_disk_file::dup (fhandler_base *child, int flags, DWORD src_pid) { fhandler_disk_file *fhc = (fhandler_disk_file *) child; - int ret = fhandler_base::dup (child, flags); - if (!ret && prw_handle - && !DuplicateHandle (GetCurrentProcess (), prw_handle, - GetCurrentProcess (), &fhc->prw_handle, - 0, TRUE, DUPLICATE_SAME_ACCESS)) - fhc->prw_handle = NULL; + int ret = fhandler_base::dup (child, flags, src_pid); + if (!ret && prw_handle) + { + HANDLE src_proc = GetCurrentProcess (); + if (src_pid) + if (!(src_proc = OpenProcess (PROCESS_DUP_HANDLE, false, src_pid))) + debug_printf ("can't open target process %d, %E", src_pid); + if (!src_proc || !DuplicateHandle (src_proc, prw_handle, + GetCurrentProcess (), &fhc->prw_handle, + 0, TRUE, DUPLICATE_SAME_ACCESS)) + fhc->prw_handle = NULL; + if (src_proc && src_proc != GetCurrentProcess ()) + CloseHandle (src_proc); + } return ret; } diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc index eff05d242..fe1aeb83f 100644 --- a/winsup/cygwin/fhandler_fifo.cc +++ b/winsup/cygwin/fhandler_fifo.cc @@ -1699,7 +1699,7 @@ fhandler_fifo::fcntl (int cmd, intptr_t arg) } int -fhandler_fifo::dup (fhandler_base *child, int flags) +fhandler_fifo::dup (fhandler_base *child, int flags, DWORD) { fhandler_fifo *fhf = NULL; diff --git a/winsup/cygwin/fhandler_floppy.cc b/winsup/cygwin/fhandler_floppy.cc index 2768a9cbf..0061f640f 100644 --- a/winsup/cygwin/fhandler_floppy.cc +++ b/winsup/cygwin/fhandler_floppy.cc @@ -372,7 +372,7 @@ fhandler_dev_floppy::close () } int -fhandler_dev_floppy::dup (fhandler_base *child, int flags) +fhandler_dev_floppy::dup (fhandler_base *child, int flags, DWORD) { int ret = fhandler_dev_raw::dup (child, flags); diff --git a/winsup/cygwin/fhandler_pipe.cc b/winsup/cygwin/fhandler_pipe.cc index edbaded68..5683cb6e1 100644 --- a/winsup/cygwin/fhandler_pipe.cc +++ b/winsup/cygwin/fhandler_pipe.cc @@ -186,7 +186,7 @@ fhandler_pipe::get_proc_fd_name (char *buf) } int -fhandler_pipe::dup (fhandler_base *child, int flags) +fhandler_pipe::dup (fhandler_base *child, int flags, DWORD) { fhandler_pipe *ftp = (fhandler_pipe *) child; ftp->set_popen_pid (0); diff --git a/winsup/cygwin/fhandler_raw.cc b/winsup/cygwin/fhandler_raw.cc index 7c341d895..7ff3faae2 100644 --- a/winsup/cygwin/fhandler_raw.cc +++ b/winsup/cygwin/fhandler_raw.cc @@ -79,7 +79,7 @@ fhandler_dev_raw::open (int flags, mode_t) } int -fhandler_dev_raw::dup (fhandler_base *child, int flags) +fhandler_dev_raw::dup (fhandler_base *child, int flags, DWORD) { int ret = fhandler_base::dup (child, flags); diff --git a/winsup/cygwin/fhandler_registry.cc b/winsup/cygwin/fhandler_registry.cc index 5696a4904..b7165811c 100644 --- a/winsup/cygwin/fhandler_registry.cc +++ b/winsup/cygwin/fhandler_registry.cc @@ -1100,7 +1100,7 @@ open_key (const char *name, REGSAM access, DWORD wow64, bool isValue) } int -fhandler_registry::dup (fhandler_base *child, int flags) +fhandler_registry::dup (fhandler_base *child, int flags, DWORD) { debug_printf ("here"); fhandler_registry *fhs = (fhandler_registry *) child; diff --git a/winsup/cygwin/fhandler_socket_inet.cc b/winsup/cygwin/fhandler_socket_inet.cc index bc08d3cf1..1eebd9302 100644 --- a/winsup/cygwin/fhandler_socket_inet.cc +++ b/winsup/cygwin/fhandler_socket_inet.cc @@ -544,7 +544,7 @@ fhandler_socket_wsock::fixup_after_exec () } int -fhandler_socket_wsock::dup (fhandler_base *child, int flags) +fhandler_socket_wsock::dup (fhandler_base *child, int flags, DWORD) { debug_printf ("here"); fhandler_socket_wsock *fhs = (fhandler_socket_wsock *) child; diff --git a/winsup/cygwin/fhandler_socket_local.cc b/winsup/cygwin/fhandler_socket_local.cc index c94bf828f..4ae8dcad9 100644 --- a/winsup/cygwin/fhandler_socket_local.cc +++ b/winsup/cygwin/fhandler_socket_local.cc @@ -626,7 +626,7 @@ fhandler_socket_local::af_local_set_secret (char *buf) } int -fhandler_socket_local::dup (fhandler_base *child, int flags) +fhandler_socket_local::dup (fhandler_base *child, int flags, DWORD) { if (get_flags () & O_PATH) /* We're viewing the socket as a disk file, but fhandler_base::dup diff --git a/winsup/cygwin/fhandler_socket_unix.cc b/winsup/cygwin/fhandler_socket_unix.cc index 067cfa73d..4831df8f8 100644 --- a/winsup/cygwin/fhandler_socket_unix.cc +++ b/winsup/cygwin/fhandler_socket_unix.cc @@ -1282,7 +1282,7 @@ fhandler_socket_unix::~fhandler_socket_unix () } int -fhandler_socket_unix::dup (fhandler_base *child, int flags) +fhandler_socket_unix::dup (fhandler_base *child, int flags, DWORD) { if (fhandler_socket::dup (child, flags)) { diff --git a/winsup/cygwin/fhandler_tape.cc b/winsup/cygwin/fhandler_tape.cc index a7f64ea57..1aa5efae2 100644 --- a/winsup/cygwin/fhandler_tape.cc +++ b/winsup/cygwin/fhandler_tape.cc @@ -1469,7 +1469,7 @@ fhandler_dev_tape::fstat (struct stat *buf) } int -fhandler_dev_tape::dup (fhandler_base *child, int flags) +fhandler_dev_tape::dup (fhandler_base *child, int flags, DWORD) { lock (-1); fhandler_dev_tape *fh = (fhandler_dev_tape *) child; diff --git a/winsup/cygwin/fhandler_timerfd.cc b/winsup/cygwin/fhandler_timerfd.cc index e7e223296..caa697d78 100644 --- a/winsup/cygwin/fhandler_timerfd.cc +++ b/winsup/cygwin/fhandler_timerfd.cc @@ -164,7 +164,7 @@ fhandler_timerfd::get_timerfd_handle () } int -fhandler_timerfd::dup (fhandler_base *child, int flags) +fhandler_timerfd::dup (fhandler_base *child, int flags, DWORD) { int ret = fhandler_base::dup (child, flags); diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc index 600de085c..1033a2087 100644 --- a/winsup/cygwin/fhandler_tty.cc +++ b/winsup/cygwin/fhandler_tty.cc @@ -1081,7 +1081,7 @@ out: } int -fhandler_pty_slave::dup (fhandler_base *child, int flags) +fhandler_pty_slave::dup (fhandler_base *child, int flags, DWORD) { /* This code was added in Oct 2001 for some undisclosed reason. However, setting the controlling tty on a dup causes rxvt to @@ -1098,7 +1098,7 @@ fhandler_pty_slave::dup (fhandler_base *child, int flags) } int -fhandler_pty_master::dup (fhandler_base *child, int) +fhandler_pty_master::dup (fhandler_base *child, int, DWORD) { report_tty_counts (child, "duped master", ""); return 0; diff --git a/winsup/cygwin/fhandler_virtual.cc b/winsup/cygwin/fhandler_virtual.cc index b9ee31f76..81ec67573 100644 --- a/winsup/cygwin/fhandler_virtual.cc +++ b/winsup/cygwin/fhandler_virtual.cc @@ -150,7 +150,7 @@ fhandler_virtual::lseek (off_t offset, int whence) } int -fhandler_virtual::dup (fhandler_base * child, int flags) +fhandler_virtual::dup (fhandler_base * child, int flags, DWORD) { int ret = fhandler_base::dup (child, flags);