4
0
mirror of git://sourceware.org/git/newlib-cygwin.git synced 2025-02-01 12:00:35 +08:00

Cygwin: fhandler_*::dup: add a 'src_pid' argument

This allows duplication of handles from an fhandler created in a
different process.  For now, this is implemented only for
fhandler_base and fhandler_disk_file.
This commit is contained in:
Ken Brown 2020-11-11 16:33:45 -05:00
parent cf1034bd38
commit 91ce3d3fd7
17 changed files with 67 additions and 45 deletions

View File

@ -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 ();

View File

@ -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 ();

View File

@ -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;

View File

@ -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)

View File

@ -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;
}

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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))
{

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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);