4
0
mirror of git://sourceware.org/git/newlib-cygwin.git synced 2025-02-08 10:09:32 +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; return 1;
} }
/* SRC_PID, if not zero, is the Windows pid of the source process. */
int int
fhandler_base::dup (fhandler_base *child, int) fhandler_base::dup (fhandler_base *child, int, DWORD src_pid)
{ {
debug_printf ("in fhandler_base dup"); debug_printf ("in fhandler_base dup");
int ret = -1;
HANDLE nh; 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 (!nohandle () && !archetype)
{ {
if (!DuplicateHandle (GetCurrentProcess (), get_handle (), if (!DuplicateHandle (src_proc, get_handle (),
GetCurrentProcess (), &nh, GetCurrentProcess (), &nh,
0, TRUE, DUPLICATE_SAME_ACCESS)) 0, TRUE, DUPLICATE_SAME_ACCESS))
{ {
debug_printf ("dup(%s) failed, handle %p, %E", debug_printf ("dup(%s) failed, handle %p, %E",
get_name (), get_handle ()); get_name (), get_handle ());
__seterrno (); __seterrno ();
return -1; goto out;
} }
VerifyHandle (nh); VerifyHandle (nh);
child->set_handle (nh); child->set_handle (nh);
} }
return 0; ret = 0;
out:
if (src_proc && src_proc != GetCurrentProcess ())
CloseHandle (src_proc);
return ret;
} }
int 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) || int res = fhandler_base::dup (child, flags) ||
((fhandler_base_overlapped *) child)->setup_overlapped (); ((fhandler_base_overlapped *) child)->setup_overlapped ();

View File

@ -414,7 +414,7 @@ public:
virtual off_t lseek (off_t offset, int whence); virtual off_t lseek (off_t offset, int whence);
virtual int lock (int, struct flock *); virtual int lock (int, struct flock *);
virtual int mand_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 int fpathconf (int);
virtual HANDLE mmap (caddr_t *addr, size_t len, int prot, 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); int fixup_before_fork_exec (DWORD);
void fixup_after_fork (HANDLE); void fixup_after_fork (HANDLE);
void fixup_after_exec (); void fixup_after_exec ();
int dup (fhandler_base *child, int); int dup (fhandler_base *child, int, DWORD = 0);
#ifdef __INSIDE_CYGWIN_NET__ #ifdef __INSIDE_CYGWIN_NET__
protected: protected:
@ -823,7 +823,7 @@ class fhandler_socket_local: public fhandler_socket_wsock
fhandler_socket_local (); fhandler_socket_local ();
~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 socket (int af, int type, int protocol, int flags);
int socketpair (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 ();
~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); DWORD wait_pipe_thread (PUNICODE_STRING pipe_name);
@ -1244,7 +1244,7 @@ public:
void fixup_after_exec (); void fixup_after_exec ();
int close (); int close ();
int dup (fhandler_base *child, int); int dup (fhandler_base *child, int, DWORD = 0);
void check_later (); void check_later ();
static void __reg1 flush_all_async_io ();; static void __reg1 flush_all_async_io ();;
@ -1295,7 +1295,7 @@ public:
select_record *select_except (select_stuff *); select_record *select_except (select_stuff *);
char *get_proc_fd_name (char *buf); char *get_proc_fd_name (char *buf);
int open (int flags, mode_t mode = 0); 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 ioctl (unsigned int cmd, void *);
int __reg2 fstat (struct stat *buf); int __reg2 fstat (struct stat *buf);
int __reg2 fstatvfs (struct statvfs *buf); int __reg2 fstatvfs (struct statvfs *buf);
@ -1549,7 +1549,7 @@ public:
off_t lseek (off_t offset, int whence); off_t lseek (off_t offset, int whence);
int close (); int close ();
int fcntl (int cmd, intptr_t); 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; } bool isfifo () const { return true; }
void set_close_on_exec (bool val); void set_close_on_exec (bool val);
void __reg3 raw_read (void *ptr, size_t& ulen); 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 __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); int ioctl (unsigned int cmd, void *buf);
void fixup_after_fork (HANDLE); 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 open (int flags, mode_t mode = 0);
int close (); 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); void __reg3 raw_read (void *ptr, size_t& ulen);
ssize_t __reg3 raw_write (const void *ptr, size_t ulen); ssize_t __reg3 raw_write (const void *ptr, size_t ulen);
off_t lseek (off_t offset, int whence); 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 __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 fixup_after_fork (HANDLE parent);
virtual void set_close_on_exec (bool val); virtual void set_close_on_exec (bool val);
virtual int ioctl (unsigned int cmd, void *buf); 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 open (int flags, mode_t mode);
int close (); int close ();
int fcntl (int cmd, intptr_t); 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); void fixup_after_fork (HANDLE parent);
int mand_lock (int, struct flock *); int mand_lock (int, struct flock *);
int __reg2 fstat (struct stat *buf); int __reg2 fstat (struct stat *buf);
@ -2218,7 +2218,7 @@ private:
int open (int flags, mode_t mode); int open (int flags, mode_t mode);
void open_setup (int flags); 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); void __reg3 read (void *ptr, size_t& len);
ssize_t __stdcall write (const 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 ioctl (unsigned int cmd, void *);
int close (); int close ();
void cleanup (); 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_fork (HANDLE parent);
void fixup_after_exec (); void fixup_after_exec ();
@ -2456,7 +2456,7 @@ public:
bool hit_eof (); bool hit_eof ();
bool setup (); bool setup ();
int dup (fhandler_base *, int); int dup (fhandler_base *, int, DWORD = 0);
void fixup_after_fork (HANDLE parent); void fixup_after_fork (HANDLE parent);
void fixup_after_exec (); void fixup_after_exec ();
int tcgetpgrp (); int tcgetpgrp ();
@ -2601,7 +2601,7 @@ class fhandler_dev_clipboard: public fhandler_base
off_t lseek (off_t offset, int whence); off_t lseek (off_t offset, int whence);
int close (); int close ();
int dup (fhandler_base *child, int); int dup (fhandler_base *child, int, DWORD = 0);
void fixup_after_exec (); void fixup_after_exec ();
size_t get_size () const { return sizeof *this; } 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); ssize_t __stdcall write (const void *ptr, size_t len);
void __reg3 read (void *ptr, size_t& len); void __reg3 read (void *ptr, size_t& len);
off_t lseek (off_t, int); 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 open (int flags, mode_t mode = 0);
int close (); int close ();
int __reg2 fstatvfs (struct statvfs *buf); int __reg2 fstatvfs (struct statvfs *buf);
@ -2930,7 +2930,7 @@ class fhandler_registry: public fhandler_proc
int __reg2 fstat (struct stat *buf); int __reg2 fstat (struct stat *buf);
bool fill_filebuf (); bool fill_filebuf ();
int close (); int close ();
int dup (fhandler_base *child, int); int dup (fhandler_base *child, int, DWORD = 0);
size_t get_size () const { return sizeof *this; } size_t get_size () const { return sizeof *this; }
@ -3111,7 +3111,7 @@ class fhandler_timerfd : public fhandler_base
int __reg2 fstat (struct stat *buf); int __reg2 fstat (struct stat *buf);
void __reg3 read (void *ptr, size_t& len); void __reg3 read (void *ptr, size_t& len);
ssize_t __stdcall write (const void *, size_t); 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 ioctl (unsigned int, void *);
int close (); int close ();

View File

@ -48,7 +48,7 @@ fhandler_dev_clipboard::fhandler_dev_clipboard ()
*/ */
int 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; fhandler_dev_clipboard *fhc = (fhandler_dev_clipboard *) child;
fhc->pos = fhc->msize = 0; 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 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 */ /* See comments in fhandler_pty_slave::dup */
if (myself->ctty != -2) if (myself->ctty != -2)

View File

@ -1435,16 +1435,24 @@ fhandler_disk_file::fcntl (int cmd, intptr_t arg)
} }
int 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; fhandler_disk_file *fhc = (fhandler_disk_file *) child;
int ret = fhandler_base::dup (child, flags); int ret = fhandler_base::dup (child, flags, src_pid);
if (!ret && prw_handle if (!ret && prw_handle)
&& !DuplicateHandle (GetCurrentProcess (), 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, GetCurrentProcess (), &fhc->prw_handle,
0, TRUE, DUPLICATE_SAME_ACCESS)) 0, TRUE, DUPLICATE_SAME_ACCESS))
fhc->prw_handle = NULL; fhc->prw_handle = NULL;
if (src_proc && src_proc != GetCurrentProcess ())
CloseHandle (src_proc);
}
return ret; return ret;
} }

View File

@ -1699,7 +1699,7 @@ fhandler_fifo::fcntl (int cmd, intptr_t arg)
} }
int int
fhandler_fifo::dup (fhandler_base *child, int flags) fhandler_fifo::dup (fhandler_base *child, int flags, DWORD)
{ {
fhandler_fifo *fhf = NULL; fhandler_fifo *fhf = NULL;

View File

@ -372,7 +372,7 @@ fhandler_dev_floppy::close ()
} }
int 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); int ret = fhandler_dev_raw::dup (child, flags);

View File

@ -186,7 +186,7 @@ fhandler_pipe::get_proc_fd_name (char *buf)
} }
int int
fhandler_pipe::dup (fhandler_base *child, int flags) fhandler_pipe::dup (fhandler_base *child, int flags, DWORD)
{ {
fhandler_pipe *ftp = (fhandler_pipe *) child; fhandler_pipe *ftp = (fhandler_pipe *) child;
ftp->set_popen_pid (0); ftp->set_popen_pid (0);

View File

@ -79,7 +79,7 @@ fhandler_dev_raw::open (int flags, mode_t)
} }
int 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); 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 int
fhandler_registry::dup (fhandler_base *child, int flags) fhandler_registry::dup (fhandler_base *child, int flags, DWORD)
{ {
debug_printf ("here"); debug_printf ("here");
fhandler_registry *fhs = (fhandler_registry *) child; fhandler_registry *fhs = (fhandler_registry *) child;

View File

@ -544,7 +544,7 @@ fhandler_socket_wsock::fixup_after_exec ()
} }
int int
fhandler_socket_wsock::dup (fhandler_base *child, int flags) fhandler_socket_wsock::dup (fhandler_base *child, int flags, DWORD)
{ {
debug_printf ("here"); debug_printf ("here");
fhandler_socket_wsock *fhs = (fhandler_socket_wsock *) child; fhandler_socket_wsock *fhs = (fhandler_socket_wsock *) child;

View File

@ -626,7 +626,7 @@ fhandler_socket_local::af_local_set_secret (char *buf)
} }
int 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) if (get_flags () & O_PATH)
/* We're viewing the socket as a disk file, but fhandler_base::dup /* 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 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)) if (fhandler_socket::dup (child, flags))
{ {

View File

@ -1469,7 +1469,7 @@ fhandler_dev_tape::fstat (struct stat *buf)
} }
int int
fhandler_dev_tape::dup (fhandler_base *child, int flags) fhandler_dev_tape::dup (fhandler_base *child, int flags, DWORD)
{ {
lock (-1); lock (-1);
fhandler_dev_tape *fh = (fhandler_dev_tape *) child; fhandler_dev_tape *fh = (fhandler_dev_tape *) child;

View File

@ -164,7 +164,7 @@ fhandler_timerfd::get_timerfd_handle ()
} }
int 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); int ret = fhandler_base::dup (child, flags);

View File

@ -1081,7 +1081,7 @@ out:
} }
int 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. /* This code was added in Oct 2001 for some undisclosed reason.
However, setting the controlling tty on a dup causes rxvt to 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 int
fhandler_pty_master::dup (fhandler_base *child, int) fhandler_pty_master::dup (fhandler_base *child, int, DWORD)
{ {
report_tty_counts (child, "duped master", ""); report_tty_counts (child, "duped master", "");
return 0; return 0;

View File

@ -150,7 +150,7 @@ fhandler_virtual::lseek (off_t offset, int whence)
} }
int 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); int ret = fhandler_base::dup (child, flags);