Define static helper functions serialize/deserialize in
fhandler_socket_unix.cc. These will be used to support sending file
descriptors via SCM_RIGHTS control messages.
The serialize function creates an 'fh_ser' structure that contains a
copy of the fhandler associated with the file descriptor, with all
allocated memory freed. The structure also contains the Windows pid
of the current process, which deserialize can use for duplicating
handles.
The deserialize function reconstructs an fhandler from an fh_ser
structure, with the handles duplicated into its own process.
For now, serialization and deserialization are fully implemented only
for disk files, and even in that case there are many FIXMEs that need
attention.
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 includes various changes to create_cmsg_data and
evaluate_cmsg_data. The most important are:
- create_cmsg_data now allows only one SCM_RIGHTS message and one
SCM_CREDENTIALS message.
- evaluate_cmsg_data now truncates the ancillary data to the number of
control messages that will fit in the supplied buffer. Previously
it discarded all control messages if the buffer was too small.
See https://man7.org/linux/man-pages/man7/unix.7.html.
Previously, create_cmsg_data and evaluate_cmsg_data required the
ancillary data to contain only a single control message, of type
SCM_CREDENTIALS. In preparation for supporting SCM_RIGHTS in the
future, allow more than one.
create_cmsg_data now iterates through the specified control messages
and allows both SCM_CREDENTIALS and SCM_RIGHTS. If no SCM_CREDENTIALS
message is present, it creates one. This was previously done in
sendmsg.
evaluate_cmsg_data also iterates through the received control messages
and allows both SCM_CREDENTIALS and SCM_RIGHTS. Control messages of
type SCM_CREDENTIALS are discarded unless the SO_PASSCRED option has
been set.
Update tests.
Add a new HANDLE argument to peek_pipe and peek_pipe_poll so that the
caller can specify a pipe handle to use in lieu of get_handle(). Use
this in recvmsg to make the MSG_PEEK flag work for unbound datagram
sockets.
Untested.
If the caller doesn't specify ancillary data, add credentials to the
outgoing packet.
This enables us to satisfy the requirement
(https://man7.org/linux/man-pages/man7/unix.7.html) that a socket with
the SO_PASSCRED option enabled can get the credentials of its peer in
every message it receives.
FIXME: I'm not sure if this is the right way to satisfy that
requirement. A possible alternative would be to arrange for a socket
to be notified when its peer enables SO_PASSCRED.
Call set_nonblocking before creating the pipe so that the pipe is
created with the correct blocking mode.
Also call set_pipe_non_blocking on the second socket so that the
client end of the pipe has the correct blocking mode. This also makes
sure that the client end of the pipe is set to message mode for
reading.
If the caller has requested the source address, try to get it on each
iteration of the main read loop, not just the first. Set msg_namelen
to 0 if it is never received.
If a packet containing control message data is received, don't read
any more packets, even if MSG_WAITALL is set.
If there's unread data in the pipe from a previous partial read of a
packet, just return. There can't be an administrative packet waiting
to be read in that case.
And use it in recvmsg.
I'm not sure this implementation is what was intended when the
evaluate_cmsg_data method was added.
For now, just support an ancillary data block consisting of a single
cmsghdr, containing SCM_CREDENTIALS.
For convenience, add a 'mshdr *' argument and make the 'cloexec'
argument false by default. The 'cloexec' argument is not currently
used, and I want to avoid having to artificially specify a value for
it when recvmsg calls evaluate_cmsg_data.
For now, just support an ancillary data block consisting of a single
cmsghdr, containing SCM_CREDENTIALS.
FIXME: We're supposed to check the credentials.
Use sizeof (af_unix_shmem_t) as the view size, as when the shared
memory was created. Previously PAGESIZE was used, causing
NtMapViewOfSection to fail with STATUS_INVALID_VIEW_SIZE.
Call grab_admin_pkt at appropriate times to check whether we've been
shut down for reading. Also, update our shutdown state whenever we
read a packet.
Untested.
FIXME: I'm not sure whether I've treated datagram sockets properly.
Extract from grab_admin_pkg two new methods, record_shut_info and
process_admin_pkg. Also add a new 'peek' argument to grab_admin_pkg.
If this is true, peek to see if the next packet in the pipe is an
administrative packet. Otherwise, assume we already know it is.
Tested by running the server/client programs from Kerrisk, "The Linux
Programming Interface", Sections 57.2 and 57.3.
Support for MSG_PEEK is not yet implemented.
Many things have not yet been tested.
If __WITH_AF_UNIX is defined when Cygwin is built, then a named
AF_UNIX socket is represented by a reparse point with a
Cygwin-specific tag and GUID. Make such files recognizable as reparse
points (but not as sockets) even if __WITH_AF_UNIX is not defined.
That way utilities such as 'ls' and 'rm' still behave reasonably.
This requires two changes:
- Define the GUID __cygwin_socket_guid unconditionally.
- Make check_reparse_point_target return PATH_REP on a reparse point
of this type if __WITH_AF_UNIX is not defined.
fhandler_socket_unix::fixup_after_exec incorrectly calls
fhandler_socket_unix::fixup_after_fork with a NULL parent process
handle. Not only that calling DuplicateHandle with a NULL parent
handle fails, but it's utterly wrong trying to duplicate the handles
at all here.
Rather just set some important values to NULL and reopen the shared
memory region. Create a fixup_helper method to call common code from
fixup_after_fork and fixup_after_exec.
Add comments to other invocations of fixup_after_fork with NULL
handle to mark them as correct this way.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
reopen_shmem is accidentally called on the parent fhandler
rather than the child fhandler, and it's called too early.
Make sure to call it on the child and only after its shmem_handle
is valid.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
Use 'waitret' instead of 'ret' for the return value of cygwait, since
there is already a different 'ret' variable in use. The previous
double use of 'ret' was legal because of scoping rules, but possibly
confusing.