mirror of
git://sourceware.org/git/newlib-cygwin.git
synced 2025-02-08 18:19:08 +08:00
Cygwin: AF_UNIX: SCM_RIGHTS: support socket descriptors
This requires modifying fhandler_socket_wsock::dup and fhandler_socket_unix::dup to use the src_pid argument. First cut. Not yet tested.
This commit is contained in:
parent
877427fbaa
commit
3b8be197f7
@ -544,52 +544,69 @@ fhandler_socket_wsock::fixup_after_exec ()
|
||||
}
|
||||
|
||||
int
|
||||
fhandler_socket_wsock::dup (fhandler_base *child, int flags, DWORD)
|
||||
fhandler_socket_wsock::dup (fhandler_base *child, int flags, DWORD src_pid)
|
||||
{
|
||||
debug_printf ("here");
|
||||
fhandler_socket_wsock *fhs = (fhandler_socket_wsock *) child;
|
||||
int ret = -1;
|
||||
HANDLE src_proc = GetCurrentProcess ();
|
||||
|
||||
if (!DuplicateHandle (GetCurrentProcess (), wsock_mtx,
|
||||
if (src_pid && !(src_proc = OpenProcess (PROCESS_DUP_HANDLE, false, src_pid)))
|
||||
{
|
||||
debug_printf ("can't open source process %d, %E", src_pid);
|
||||
__seterrno ();
|
||||
return -1;
|
||||
}
|
||||
if (!DuplicateHandle (src_proc, wsock_mtx,
|
||||
GetCurrentProcess (), &fhs->wsock_mtx,
|
||||
0, TRUE, DUPLICATE_SAME_ACCESS))
|
||||
{
|
||||
__seterrno ();
|
||||
return -1;
|
||||
goto out;
|
||||
}
|
||||
if (!DuplicateHandle (GetCurrentProcess (), wsock_evt,
|
||||
if (!DuplicateHandle (src_proc, wsock_evt,
|
||||
GetCurrentProcess (), &fhs->wsock_evt,
|
||||
0, TRUE, DUPLICATE_SAME_ACCESS))
|
||||
{
|
||||
__seterrno ();
|
||||
NtClose (fhs->wsock_mtx);
|
||||
return -1;
|
||||
goto out;
|
||||
}
|
||||
if (!need_fixup_before ())
|
||||
{
|
||||
int ret = fhandler_base::dup (child, flags);
|
||||
ret = fhandler_base::dup (child, flags, src_pid);
|
||||
if (ret)
|
||||
{
|
||||
NtClose (fhs->wsock_evt);
|
||||
NtClose (fhs->wsock_mtx);
|
||||
}
|
||||
return ret;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (src_proc != GetCurrentProcess ())
|
||||
{
|
||||
/* FIXME: Can we support this? Is it worth the trouble? */
|
||||
set_errno (EOPNOTSUPP);
|
||||
goto out;
|
||||
}
|
||||
cygheap->user.deimpersonate ();
|
||||
fhs->init_fixup_before ();
|
||||
fhs->set_handle (get_handle ());
|
||||
int ret = fhs->fixup_before_fork_exec (GetCurrentProcessId ());
|
||||
ret = fhs->fixup_before_fork_exec (GetCurrentProcessId ());
|
||||
cygheap->user.reimpersonate ();
|
||||
if (!ret)
|
||||
{
|
||||
fhs->fixup_after_fork (GetCurrentProcess ());
|
||||
if (fhs->get_handle() != (HANDLE) INVALID_SOCKET)
|
||||
return 0;
|
||||
goto out;
|
||||
}
|
||||
cygheap->fdtab.dec_need_fixup_before ();
|
||||
NtClose (fhs->wsock_evt);
|
||||
NtClose (fhs->wsock_mtx);
|
||||
return -1;
|
||||
out:
|
||||
if (src_proc != GetCurrentProcess ())
|
||||
NtClose (src_proc);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -1296,43 +1296,56 @@ fhandler_socket_unix::~fhandler_socket_unix ()
|
||||
}
|
||||
|
||||
int
|
||||
fhandler_socket_unix::dup (fhandler_base *child, int flags, DWORD)
|
||||
fhandler_socket_unix::dup (fhandler_base *child, int flags, DWORD src_pid)
|
||||
{
|
||||
if (fhandler_socket::dup (child, flags))
|
||||
int ret = -1;
|
||||
HANDLE src_proc = GetCurrentProcess ();
|
||||
fhandler_socket_unix *fhs = (fhandler_socket_unix *) child;
|
||||
|
||||
if (src_pid && !(src_proc = OpenProcess (PROCESS_DUP_HANDLE, false, src_pid)))
|
||||
{
|
||||
debug_printf ("can't open source process %d, %E", src_pid);
|
||||
__seterrno ();
|
||||
return -1;
|
||||
}
|
||||
fhandler_socket_unix *fhs = (fhandler_socket_unix *) child;
|
||||
if (get_handle () && fhandler_socket::dup (child, flags, src_pid) < 0)
|
||||
{
|
||||
__seterrno ();
|
||||
goto out;
|
||||
}
|
||||
if (backing_file_handle && backing_file_handle != INVALID_HANDLE_VALUE
|
||||
&& !DuplicateHandle (GetCurrentProcess (), backing_file_handle,
|
||||
&& !DuplicateHandle (src_proc, backing_file_handle,
|
||||
GetCurrentProcess (), &fhs->backing_file_handle,
|
||||
0, TRUE, DUPLICATE_SAME_ACCESS))
|
||||
{
|
||||
__seterrno ();
|
||||
fhs->close ();
|
||||
return -1;
|
||||
goto out;
|
||||
}
|
||||
if (!DuplicateHandle (GetCurrentProcess (), shmem_handle,
|
||||
if (!DuplicateHandle (src_proc, shmem_handle,
|
||||
GetCurrentProcess (), &fhs->shmem_handle,
|
||||
0, TRUE, DUPLICATE_SAME_ACCESS))
|
||||
{
|
||||
__seterrno ();
|
||||
fhs->close ();
|
||||
return -1;
|
||||
goto out;
|
||||
}
|
||||
if (fhs->reopen_shmem () < 0)
|
||||
{
|
||||
__seterrno ();
|
||||
fhs->close ();
|
||||
return -1;
|
||||
goto out;
|
||||
}
|
||||
fhs->sun_path (sun_path ());
|
||||
fhs->peer_sun_path (peer_sun_path ());
|
||||
fhs->connect_wait_thr = NULL;
|
||||
fhs->cwt_termination_evt = NULL;
|
||||
fhs->cwt_param = NULL;
|
||||
return 0;
|
||||
ret = 0;
|
||||
out:
|
||||
if (src_proc != GetCurrentProcess ())
|
||||
NtClose (src_proc);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Waiter thread method. Here we wait for a pipe instance to become
|
||||
@ -1989,17 +2002,69 @@ fhandler_socket_unix::serialize (int fd)
|
||||
if (cfd < 0)
|
||||
{
|
||||
set_errno (EBADF);
|
||||
goto out;
|
||||
return NULL;
|
||||
}
|
||||
/* For the moment we support disk files only. */
|
||||
if (cfd->get_device () != FH_FS)
|
||||
device dev = cfd->dev ();
|
||||
switch (dev.get_major ())
|
||||
{
|
||||
case DEV_PTYS_MAJOR:
|
||||
case DEV_PTYM_MAJOR:
|
||||
case DEV_FLOPPY_MAJOR:
|
||||
case DEV_CDROM_MAJOR:
|
||||
case DEV_SD_MAJOR:
|
||||
case DEV_SD1_MAJOR ... DEV_SD7_MAJOR:
|
||||
case DEV_SD_HIGHPART_START ... DEV_SD_HIGHPART_END:
|
||||
case DEV_TAPE_MAJOR:
|
||||
case DEV_SERIAL_MAJOR:
|
||||
case DEV_CONS_MAJOR:
|
||||
set_errno (EOPNOTSUPP);
|
||||
goto out;
|
||||
}
|
||||
default:
|
||||
switch ((dev_t) dev)
|
||||
{
|
||||
case FH_FS:
|
||||
case FH_INET:
|
||||
case FH_UNIX:
|
||||
newfh = cygheap->fdtab.dup_worker (cfd, 0);
|
||||
if (!newfh)
|
||||
goto out;
|
||||
break;
|
||||
/* The FH_LOCAL case shouldn't occur. */
|
||||
case FH_LOCAL:
|
||||
case FH_CONSOLE:
|
||||
case FH_CONIN:
|
||||
case FH_CONOUT:
|
||||
case FH_PTMX:
|
||||
case FH_WINDOWS:
|
||||
case FH_FIFO:
|
||||
case FH_PIPE:
|
||||
case FH_PIPER:
|
||||
case FH_PIPEW:
|
||||
case FH_NULL:
|
||||
case FH_ZERO:
|
||||
case FH_FULL:
|
||||
case FH_RANDOM:
|
||||
case FH_URANDOM:
|
||||
case FH_CLIPBOARD:
|
||||
case FH_OSS_DSP:
|
||||
case FH_PROC:
|
||||
case FH_REGISTRY:
|
||||
case FH_PROCESS:
|
||||
case FH_PROCESSFD:
|
||||
case FH_PROCNET:
|
||||
case FH_PROCSYS:
|
||||
case FH_PROCSYSVIPC:
|
||||
case FH_NETDRIVE:
|
||||
case FH_DEV:
|
||||
case FH_CYGDRIVE:
|
||||
case FH_SIGNALFD:
|
||||
case FH_TIMERFD:
|
||||
case FH_TTY:
|
||||
default:
|
||||
set_errno (EOPNOTSUPP);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
/* Free allocated memory in clone. */
|
||||
newfh->pc.free_strings ();
|
||||
newfh->dev ().free_strings ();
|
||||
@ -2028,21 +2093,72 @@ fhandler_socket_unix::deserialize (void *bufp)
|
||||
fhandler_base *oldfh, *newfh;
|
||||
DWORD winpid = fhs->winpid;
|
||||
|
||||
/* What kind of fhandler is this? */
|
||||
dev_t dev = ((fhandler_base *) &fhs->fhu)->get_device ();
|
||||
|
||||
/* FIXME: Based on dev, we want to cast fhs to the right kind of
|
||||
fhandler pointer. I guess this requires a big switch statement,
|
||||
as in dtable.cc:fh_alloc.
|
||||
|
||||
For now, we just support disk files. */
|
||||
|
||||
if (dev != FH_FS)
|
||||
/* What kind of fhandler is this? (See dtable.cc:fh_alloc.) */
|
||||
device dev = ((fhandler_base *) &fhs->fhu)->dev ();
|
||||
switch (dev.get_major ())
|
||||
{
|
||||
case DEV_PTYS_MAJOR:
|
||||
case DEV_PTYM_MAJOR:
|
||||
case DEV_FLOPPY_MAJOR:
|
||||
case DEV_CDROM_MAJOR:
|
||||
case DEV_SD_MAJOR:
|
||||
case DEV_SD1_MAJOR ... DEV_SD7_MAJOR:
|
||||
case DEV_SD_HIGHPART_START ... DEV_SD_HIGHPART_END:
|
||||
case DEV_TAPE_MAJOR:
|
||||
case DEV_SERIAL_MAJOR:
|
||||
case DEV_CONS_MAJOR:
|
||||
set_errno (EOPNOTSUPP);
|
||||
send_scm_fd_ack (fhs->uniq_id);
|
||||
return -1;
|
||||
default:
|
||||
switch ((dev_t) dev)
|
||||
{
|
||||
case FH_FS:
|
||||
oldfh = (fhandler_disk_file *) &fhs->fhu;
|
||||
break;
|
||||
case FH_INET:
|
||||
oldfh = (fhandler_socket_inet *) &fhs->fhu;
|
||||
break;
|
||||
case FH_UNIX:
|
||||
oldfh = (fhandler_socket_unix *) &fhs->fhu;
|
||||
break;
|
||||
/* The FH_LOCAL case shouldn't occur. */
|
||||
case FH_LOCAL:
|
||||
case FH_CONSOLE:
|
||||
case FH_CONIN:
|
||||
case FH_CONOUT:
|
||||
case FH_PTMX:
|
||||
case FH_WINDOWS:
|
||||
case FH_FIFO:
|
||||
case FH_PIPE:
|
||||
case FH_PIPER:
|
||||
case FH_PIPEW:
|
||||
case FH_NULL:
|
||||
case FH_ZERO:
|
||||
case FH_FULL:
|
||||
case FH_RANDOM:
|
||||
case FH_URANDOM:
|
||||
case FH_CLIPBOARD:
|
||||
case FH_OSS_DSP:
|
||||
case FH_PROC:
|
||||
case FH_REGISTRY:
|
||||
case FH_PROCESS:
|
||||
case FH_PROCESSFD:
|
||||
case FH_PROCNET:
|
||||
case FH_PROCSYS:
|
||||
case FH_PROCSYSVIPC:
|
||||
case FH_NETDRIVE:
|
||||
case FH_DEV:
|
||||
case FH_CYGDRIVE:
|
||||
case FH_SIGNALFD:
|
||||
case FH_TIMERFD:
|
||||
case FH_TTY:
|
||||
default:
|
||||
set_errno (EOPNOTSUPP);
|
||||
send_scm_fd_ack (fhs->uniq_id);
|
||||
return -1;
|
||||
}
|
||||
oldfh = (fhandler_disk_file *) &fhs->fhu;
|
||||
}
|
||||
cygheap_fdnew cfd;
|
||||
if (cfd < 0)
|
||||
return -1;
|
||||
@ -2051,7 +2167,18 @@ fhandler_socket_unix::deserialize (void *bufp)
|
||||
debug_printf ("can't send ack");
|
||||
if (!newfh)
|
||||
return -1;
|
||||
switch ((dev_t) dev)
|
||||
{
|
||||
case FH_FS:
|
||||
newfh->set_name_from_handle ();
|
||||
break;
|
||||
case FH_UNIX:
|
||||
if (((fhandler_socket_unix *) newfh)->get_pipe_end () == pipe_server)
|
||||
((fhandler_socket_unix *) newfh)->gen_pipe_name ();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
cfd = newfh;
|
||||
return cfd;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user