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;
|
unsigned int server_cpus = 0;
|
||||||
int is_wow64 = FALSE;
|
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 */
|
timeout_t server_start_time = 0; /* time of server startup */
|
||||||
|
|
||||||
sigset_t server_block_set; /* signals to block during server calls */
|
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 )
|
void CDECL wine_server_send_fd( int fd )
|
||||||
{
|
{
|
||||||
#ifndef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
|
|
||||||
struct cmsg_fd cmsg;
|
|
||||||
#endif
|
|
||||||
struct send_fd data;
|
struct send_fd data;
|
||||||
struct msghdr msghdr;
|
struct msghdr msghdr;
|
||||||
struct iovec vec;
|
struct iovec vec;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
vec.iov_base = (void *)&data;
|
#ifdef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
|
||||||
vec.iov_len = sizeof(data);
|
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_name = NULL;
|
||||||
msghdr.msg_namelen = 0;
|
msghdr.msg_namelen = 0;
|
||||||
msghdr.msg_iov = &vec;
|
msghdr.msg_iov = &vec;
|
||||||
msghdr.msg_iovlen = 1;
|
msghdr.msg_iovlen = 1;
|
||||||
|
|
||||||
#ifdef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
|
vec.iov_base = (void *)&data;
|
||||||
msghdr.msg_accrights = (void *)&fd;
|
vec.iov_len = sizeof(data);
|
||||||
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 */
|
|
||||||
|
|
||||||
data.tid = GetCurrentThreadId();
|
data.tid = GetCurrentThreadId();
|
||||||
data.fd = fd;
|
data.fd = fd;
|
||||||
|
@ -385,24 +372,16 @@ void CDECL wine_server_send_fd( int fd )
|
||||||
static int receive_fd( obj_handle_t *handle )
|
static int receive_fd( obj_handle_t *handle )
|
||||||
{
|
{
|
||||||
struct iovec vec;
|
struct iovec vec;
|
||||||
int ret, fd;
|
struct msghdr msghdr;
|
||||||
|
int ret, fd = -1;
|
||||||
|
|
||||||
#ifdef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
|
#ifdef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
|
||||||
struct msghdr msghdr;
|
|
||||||
|
|
||||||
fd = -1;
|
|
||||||
msghdr.msg_accrights = (void *)&fd;
|
msghdr.msg_accrights = (void *)&fd;
|
||||||
msghdr.msg_accrightslen = sizeof(fd);
|
msghdr.msg_accrightslen = sizeof(fd);
|
||||||
#else /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
|
#else /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
|
||||||
struct msghdr msghdr;
|
char cmsg_buffer[256];
|
||||||
struct cmsg_fd cmsg;
|
msghdr.msg_control = cmsg_buffer;
|
||||||
|
msghdr.msg_controllen = sizeof(cmsg_buffer);
|
||||||
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);
|
|
||||||
msghdr.msg_flags = 0;
|
msghdr.msg_flags = 0;
|
||||||
#endif /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
|
#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)
|
if ((ret = recvmsg( fd_socket, &msghdr, MSG_CMSG_CLOEXEC )) > 0)
|
||||||
{
|
{
|
||||||
#ifndef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
|
#ifndef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
|
||||||
fd = cmsg.fd;
|
struct cmsghdr *cmsg;
|
||||||
#endif
|
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 */
|
if (fd != -1) fcntl( fd, F_SETFD, FD_CLOEXEC ); /* in case MSG_CMSG_CLOEXEC is not supported */
|
||||||
return fd;
|
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 master_socket *master_socket; /* the master socket object */
|
||||||
static struct timeout_user *master_timeout;
|
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 */
|
/* complain about a protocol error and terminate the client connection */
|
||||||
void fatal_protocol_error( struct thread *thread, const char *err, ... )
|
void fatal_protocol_error( struct thread *thread, const char *err, ... )
|
||||||
{
|
{
|
||||||
|
@ -359,25 +342,41 @@ error:
|
||||||
/* receive a file descriptor on the process socket */
|
/* receive a file descriptor on the process socket */
|
||||||
int receive_fd( struct process *process )
|
int receive_fd( struct process *process )
|
||||||
{
|
{
|
||||||
|
struct iovec vec;
|
||||||
struct send_fd data;
|
struct send_fd data;
|
||||||
int fd, ret;
|
struct msghdr msghdr;
|
||||||
|
int fd = -1, ret;
|
||||||
|
|
||||||
#ifdef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
|
#ifdef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
|
||||||
msghdr.msg_accrightslen = sizeof(int);
|
msghdr.msg_accrightslen = sizeof(int);
|
||||||
msghdr.msg_accrights = (void *)&fd;
|
msghdr.msg_accrights = (void *)&fd;
|
||||||
#else /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
|
#else /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
|
||||||
msghdr.msg_control = &cmsg;
|
char cmsg_buffer[256];
|
||||||
msghdr.msg_controllen = sizeof(cmsg.header) + sizeof(fd);
|
msghdr.msg_control = cmsg_buffer;
|
||||||
cmsg.fd = -1;
|
msghdr.msg_controllen = sizeof(cmsg_buffer);
|
||||||
|
msghdr.msg_flags = 0;
|
||||||
#endif /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
|
#endif /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
|
||||||
|
|
||||||
myiovec.iov_base = (void *)&data;
|
msghdr.msg_name = NULL;
|
||||||
myiovec.iov_len = sizeof(data);
|
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 );
|
ret = recvmsg( get_unix_fd( process->msg_fd ), &msghdr, 0 );
|
||||||
|
|
||||||
#ifndef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
|
#ifndef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
|
||||||
fd = cmsg.fd;
|
if (ret > 0)
|
||||||
#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 (ret == sizeof(data))
|
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",
|
fprintf( stderr, "Protocol error: process %04x: partial recvmsg %d for fd\n",
|
||||||
process->id, ret );
|
process->id, ret );
|
||||||
|
if (fd != -1) close( fd );
|
||||||
kill_process( process, 1 );
|
kill_process( process, 1 );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -429,23 +429,37 @@ int receive_fd( struct process *process )
|
||||||
/* send an fd to a client */
|
/* send an fd to a client */
|
||||||
int send_client_fd( struct process *process, int fd, obj_handle_t handle )
|
int send_client_fd( struct process *process, int fd, obj_handle_t handle )
|
||||||
{
|
{
|
||||||
|
struct iovec vec;
|
||||||
|
struct msghdr msghdr;
|
||||||
int ret;
|
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
|
#ifdef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
|
||||||
msghdr.msg_accrightslen = sizeof(fd);
|
msghdr.msg_accrightslen = sizeof(fd);
|
||||||
msghdr.msg_accrights = (void *)&fd;
|
msghdr.msg_accrights = (void *)&fd;
|
||||||
#else /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
|
#else /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
|
||||||
msghdr.msg_control = &cmsg;
|
char cmsg_buffer[256];
|
||||||
msghdr.msg_controllen = sizeof(cmsg.header) + sizeof(fd);
|
struct cmsghdr *cmsg;
|
||||||
cmsg.fd = fd;
|
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 */
|
#endif /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
|
||||||
|
|
||||||
myiovec.iov_base = (void *)&handle;
|
msghdr.msg_name = NULL;
|
||||||
myiovec.iov_len = sizeof(handle);
|
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 );
|
ret = sendmsg( get_unix_fd( process->msg_fd ), &msghdr, 0 );
|
||||||
|
|
||||||
|
@ -797,12 +811,6 @@ void open_master_socket(void)
|
||||||
acquire_lock();
|
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 the process tracing mechanism */
|
||||||
init_tracing_mechanism();
|
init_tracing_mechanism();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue