server: Make the fd passing code slightly more portable.
This commit is contained in:
parent
19da00a6a3
commit
179715251d
|
@ -99,20 +99,6 @@ static const enum cpu_type client_cpu = CPU_ARM;
|
|||
unsigned int server_cpus = 0;
|
||||
int is_wow64 = FALSE;
|
||||
|
||||
#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 */
|
||||
|
@ -334,34 +320,35 @@ void server_leave_uninterrupted_section( RTL_CRITICAL_SECTION *cs, sigset_t *sig
|
|||
*/
|
||||
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);
|
||||
#ifdef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
|
||||
msghdr.msg_accrights = (void *)&fd;
|
||||
msghdr.msg_accrightslen = sizeof(fd);
|
||||
#else /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
|
||||
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;
|
||||
|
||||
#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);
|
||||
msghdr.msg_flags = 0;
|
||||
#endif /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
|
||||
vec.iov_base = (void *)&data;
|
||||
vec.iov_len = sizeof(data);
|
||||
|
||||
data.tid = GetCurrentThreadId();
|
||||
data.fd = fd;
|
||||
|
@ -385,24 +372,16 @@ void CDECL wine_server_send_fd( int fd )
|
|||
static int receive_fd( obj_handle_t *handle )
|
||||
{
|
||||
struct iovec vec;
|
||||
int ret, fd;
|
||||
struct msghdr msghdr;
|
||||
int ret, fd = -1;
|
||||
|
||||
#ifdef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
|
||||
struct msghdr msghdr;
|
||||
|
||||
fd = -1;
|
||||
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 */
|
||||
|
||||
|
@ -418,8 +397,13 @@ static int receive_fd( obj_handle_t *handle )
|
|||
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;
|
||||
}
|
||||
|
|
|
@ -126,23 +126,6 @@ int config_dir_fd = -1; /* file descriptor for the config dir */
|
|||
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, ... )
|
||||
{
|
||||
|
@ -359,25 +342,41 @@ error:
|
|||
/* 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))
|
||||
{
|
||||
|
@ -412,6 +411,7 @@ int receive_fd( struct process *process )
|
|||
{
|
||||
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
|
||||
|
@ -429,23 +429,37 @@ int receive_fd( struct process *process )
|
|||
/* 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 );
|
||||
|
||||
|
@ -797,12 +811,6 @@ void open_master_socket(void)
|
|||
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();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue