#define SOCKETNAME "socket" /* name of the socket file */
#define LOCKNAME "lock" /* name of the lock file */
-#ifndef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
-/* data structure used to pass an fd with sendmsg/recvmsg */
-struct cmsg_fd
-{
- struct
- {
- size_t len; /* size of structure */
- int level; /* SOL_SOCKET */
- int type; /* SCM_RIGHTS */
- } header;
- int fd; /* fd to pass */
-};
-#endif /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
-
timeout_t server_start_time = 0; /* time of server startup */
sigset_t server_block_set; /* signals to block during server calls */
*/
void CDECL wine_server_send_fd( int fd )
{
-#ifndef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
- struct cmsg_fd cmsg;
-#endif
struct send_fd data;
struct msghdr msghdr;
struct iovec vec;
int ret;
- vec.iov_base = (void *)&data;
- vec.iov_len = sizeof(data);
-
- msghdr.msg_name = NULL;
- msghdr.msg_namelen = 0;
- msghdr.msg_iov = &vec;
- msghdr.msg_iovlen = 1;
-
#ifdef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
msghdr.msg_accrights = (void *)&fd;
msghdr.msg_accrightslen = sizeof(fd);
#else /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
- cmsg.header.len = sizeof(cmsg.header) + sizeof(fd);
- cmsg.header.level = SOL_SOCKET;
- cmsg.header.type = SCM_RIGHTS;
- cmsg.fd = fd;
- msghdr.msg_control = &cmsg;
- msghdr.msg_controllen = sizeof(cmsg.header) + sizeof(fd);
+ char cmsg_buffer[256];
+ struct cmsghdr *cmsg;
+ msghdr.msg_control = cmsg_buffer;
+ msghdr.msg_controllen = sizeof(cmsg_buffer);
msghdr.msg_flags = 0;
+ cmsg = CMSG_FIRSTHDR( &msghdr );
+ cmsg->cmsg_len = CMSG_LEN( sizeof(fd) );
+ cmsg->cmsg_level = SOL_SOCKET;
+ cmsg->cmsg_type = SCM_RIGHTS;
+ *(int *)CMSG_DATA(cmsg) = fd;
+ msghdr.msg_controllen = cmsg->cmsg_len;
#endif /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
+ msghdr.msg_name = NULL;
+ msghdr.msg_namelen = 0;
+ msghdr.msg_iov = &vec;
+ msghdr.msg_iovlen = 1;
+
+ vec.iov_base = (void *)&data;
+ vec.iov_len = sizeof(data);
+
data.tid = GetCurrentThreadId();
data.fd = fd;
static int receive_fd( obj_handle_t *handle )
{
struct iovec vec;
- int ret, fd;
-
-#ifdef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
struct msghdr msghdr;
+ int ret, fd = -1;
- fd = -1;
+#ifdef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
msghdr.msg_accrights = (void *)&fd;
msghdr.msg_accrightslen = sizeof(fd);
#else /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
- struct msghdr msghdr;
- struct cmsg_fd cmsg;
-
- cmsg.header.len = sizeof(cmsg.header) + sizeof(fd);
- cmsg.header.level = SOL_SOCKET;
- cmsg.header.type = SCM_RIGHTS;
- cmsg.fd = -1;
- msghdr.msg_control = &cmsg;
- msghdr.msg_controllen = sizeof(cmsg.header) + sizeof(fd);
+ char cmsg_buffer[256];
+ msghdr.msg_control = cmsg_buffer;
+ msghdr.msg_controllen = sizeof(cmsg_buffer);
msghdr.msg_flags = 0;
#endif /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
if ((ret = recvmsg( fd_socket, &msghdr, MSG_CMSG_CLOEXEC )) > 0)
{
#ifndef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
- fd = cmsg.fd;
-#endif
+ struct cmsghdr *cmsg;
+ for (cmsg = CMSG_FIRSTHDR( &msghdr ); cmsg; cmsg = CMSG_NXTHDR( &msghdr, cmsg ))
+ {
+ if (cmsg->cmsg_level != SOL_SOCKET) continue;
+ if (cmsg->cmsg_type == SCM_RIGHTS) fd = *(int *)CMSG_DATA(cmsg);
+ }
+#endif /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
if (fd != -1) fcntl( fd, F_SETFD, FD_CLOEXEC ); /* in case MSG_CMSG_CLOEXEC is not supported */
return fd;
}
static struct master_socket *master_socket; /* the master socket object */
static struct timeout_user *master_timeout;
-/* socket communication static structures */
-static struct iovec myiovec;
-static struct msghdr msghdr;
-#ifndef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
-struct cmsg_fd
-{
- struct
- {
- size_t len; /* size of structure */
- int level; /* SOL_SOCKET */
- int type; /* SCM_RIGHTS */
- } header;
- int fd; /* fd to pass */
-};
-static struct cmsg_fd cmsg = { { sizeof(cmsg.header) + sizeof(cmsg.fd), SOL_SOCKET, SCM_RIGHTS }, -1 };
-#endif /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
-
/* complain about a protocol error and terminate the client connection */
void fatal_protocol_error( struct thread *thread, const char *err, ... )
{
/* receive a file descriptor on the process socket */
int receive_fd( struct process *process )
{
+ struct iovec vec;
struct send_fd data;
- int fd, ret;
+ struct msghdr msghdr;
+ int fd = -1, ret;
#ifdef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
msghdr.msg_accrightslen = sizeof(int);
msghdr.msg_accrights = (void *)&fd;
#else /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
- msghdr.msg_control = &cmsg;
- msghdr.msg_controllen = sizeof(cmsg.header) + sizeof(fd);
- cmsg.fd = -1;
+ char cmsg_buffer[256];
+ msghdr.msg_control = cmsg_buffer;
+ msghdr.msg_controllen = sizeof(cmsg_buffer);
+ msghdr.msg_flags = 0;
#endif /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
- myiovec.iov_base = (void *)&data;
- myiovec.iov_len = sizeof(data);
+ msghdr.msg_name = NULL;
+ msghdr.msg_namelen = 0;
+ msghdr.msg_iov = &vec;
+ msghdr.msg_iovlen = 1;
+ vec.iov_base = (void *)&data;
+ vec.iov_len = sizeof(data);
ret = recvmsg( get_unix_fd( process->msg_fd ), &msghdr, 0 );
+
#ifndef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
- fd = cmsg.fd;
-#endif
+ if (ret > 0)
+ {
+ struct cmsghdr *cmsg;
+ for (cmsg = CMSG_FIRSTHDR( &msghdr ); cmsg; cmsg = CMSG_NXTHDR( &msghdr, cmsg ))
+ {
+ if (cmsg->cmsg_level != SOL_SOCKET) continue;
+ if (cmsg->cmsg_type == SCM_RIGHTS) fd = *(int *)CMSG_DATA(cmsg);
+ }
+ }
+#endif /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
if (ret == sizeof(data))
{
{
fprintf( stderr, "Protocol error: process %04x: partial recvmsg %d for fd\n",
process->id, ret );
+ if (fd != -1) close( fd );
kill_process( process, 1 );
}
else
/* send an fd to a client */
int send_client_fd( struct process *process, int fd, obj_handle_t handle )
{
+ struct iovec vec;
+ struct msghdr msghdr;
int ret;
- if (debug_level)
- fprintf( stderr, "%04x: *fd* %04x -> %d\n",
- current ? current->id : process->id, handle, fd );
-
#ifdef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
msghdr.msg_accrightslen = sizeof(fd);
msghdr.msg_accrights = (void *)&fd;
#else /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
- msghdr.msg_control = &cmsg;
- msghdr.msg_controllen = sizeof(cmsg.header) + sizeof(fd);
- cmsg.fd = fd;
+ char cmsg_buffer[256];
+ struct cmsghdr *cmsg;
+ msghdr.msg_control = cmsg_buffer;
+ msghdr.msg_controllen = sizeof(cmsg_buffer);
+ msghdr.msg_flags = 0;
+ cmsg = CMSG_FIRSTHDR( &msghdr );
+ cmsg->cmsg_len = CMSG_LEN( sizeof(fd) );
+ cmsg->cmsg_level = SOL_SOCKET;
+ cmsg->cmsg_type = SCM_RIGHTS;
+ *(int *)CMSG_DATA(cmsg) = fd;
+ msghdr.msg_controllen = cmsg->cmsg_len;
#endif /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
- myiovec.iov_base = (void *)&handle;
- myiovec.iov_len = sizeof(handle);
+ msghdr.msg_name = NULL;
+ msghdr.msg_namelen = 0;
+ msghdr.msg_iov = &vec;
+ msghdr.msg_iovlen = 1;
+
+ vec.iov_base = (void *)&handle;
+ vec.iov_len = sizeof(handle);
+
+ if (debug_level)
+ fprintf( stderr, "%04x: *fd* %04x -> %d\n", current ? current->id : process->id, handle, fd );
ret = sendmsg( get_unix_fd( process->msg_fd ), &msghdr, 0 );
acquire_lock();
}
- /* setup msghdr structure constant fields */
- msghdr.msg_name = NULL;
- msghdr.msg_namelen = 0;
- msghdr.msg_iov = &myiovec;
- msghdr.msg_iovlen = 1;
-
/* init the process tracing mechanism */
init_tracing_mechanism();
}