~ubuntu-branches/ubuntu/wily/mir/wily-proposed

« back to all changes in this revision

Viewing changes to src/server/frontend/socket_messenger.cpp

  • Committer: Package Import Robot
  • Author(s): Ubuntu daily release
  • Date: 2014-10-10 14:01:26 UTC
  • mto: This revision was merged to the branch mainline in revision 84.
  • Revision ID: package-import@ubuntu.com-20141010140126-n1czko8na1kuz4ll
Tags: upstream-0.8.0+14.10.20141010
ImportĀ upstreamĀ versionĀ 0.8.0+14.10.20141010

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
#include "mir/frontend/client_constants.h"
21
21
#include "mir/frontend/session_credentials.h"
22
22
#include "mir/variable_length_array.h"
 
23
#include "mir/fd_socket_transmission.h"
23
24
 
24
25
#include <boost/throw_exception.hpp>
25
26
 
34
35
namespace ba = boost::asio;
35
36
 
36
37
mfd::SocketMessenger::SocketMessenger(std::shared_ptr<ba::local::stream_protocol::socket> const& socket)
37
 
    : socket(socket)
 
38
    : socket(socket),
 
39
      socket_fd{IntOwnedFd{socket->native_handle()}}
38
40
{
39
41
    // Make the socket non-blocking to avoid hanging the server when a client
40
42
    // is unresponsive. Also increase the send buffer size to 64KiB to allow
51
53
    struct ucred cr;
52
54
    socklen_t cl = sizeof(cr);
53
55
 
54
 
    auto status = getsockopt(socket->native_handle(), SOL_SOCKET, SO_PEERCRED, &cr, &cl);
 
56
    auto status = getsockopt(socket_fd, SOL_SOCKET, SO_PEERCRED, &cr, &cl);
55
57
 
56
58
    if (status)
57
59
        BOOST_THROW_EXCEPTION(std::runtime_error("Failed to query client socket credentials"));
93
95
 
94
96
void mfd::SocketMessenger::send_fds_locked(std::unique_lock<std::mutex> const&, std::vector<mir::Fd> const& fds)
95
97
{
96
 
    if (fds.size() > 0)
97
 
    {
98
 
        // We send dummy data
99
 
        struct iovec iov;
100
 
        char dummy_iov_data = 'M';
101
 
        iov.iov_base = &dummy_iov_data;
102
 
        iov.iov_len = 1;
103
 
 
104
 
        // Allocate space for control message
105
 
        static auto const builtin_n_fds = 5;
106
 
        static auto const builtin_cmsg_space = CMSG_SPACE(builtin_n_fds * sizeof(int));
107
 
        auto const fds_bytes = fds.size() * sizeof(int);
108
 
        mir::VariableLengthArray<builtin_cmsg_space> control{CMSG_SPACE(fds_bytes)};
109
 
        // Silence valgrind uninitialized memory complaint
110
 
        memset(control.data(), 0, control.size());
111
 
 
112
 
        // Message to send
113
 
        struct msghdr header;
114
 
        header.msg_name = NULL;
115
 
        header.msg_namelen = 0;
116
 
        header.msg_iov = &iov;
117
 
        header.msg_iovlen = 1;
118
 
        header.msg_controllen = control.size();
119
 
        header.msg_control = control.data();
120
 
        header.msg_flags = 0;
121
 
 
122
 
        // Control message contains file descriptors
123
 
        struct cmsghdr *message = CMSG_FIRSTHDR(&header);
124
 
        message->cmsg_len = CMSG_LEN(fds_bytes);
125
 
        message->cmsg_level = SOL_SOCKET;
126
 
        message->cmsg_type = SCM_RIGHTS;
127
 
 
128
 
        int* const data = reinterpret_cast<int*>(CMSG_DATA(message));
129
 
        int i = 0;
130
 
        for (auto& fd : fds)
131
 
            data[i++] = fd;
132
 
 
133
 
        auto const sent = sendmsg(socket->native_handle(), &header, 0);
134
 
        if (sent < 0)
135
 
            BOOST_THROW_EXCEPTION(std::runtime_error("Failed to send fds: " + std::string(strerror(errno))));
136
 
    }
 
98
    mir::send_fds(socket_fd, fds);
137
99
}
138
100
 
139
101
void mfd::SocketMessenger::async_receive_msg(
198
160
    msgh.msg_control = control_un.control;
199
161
    msgh.msg_controllen = sizeof(control_un.control);
200
162
 
201
 
    if (recvmsg(socket->native_handle(), &msgh, MSG_PEEK) != -1)
 
163
    if (recvmsg(socket_fd, &msgh, MSG_PEEK) != -1)
202
164
    {
203
165
        auto const ucredp = reinterpret_cast<ucred*>(CMSG_DATA(CMSG_FIRSTHDR(&msgh)));
204
166
        session_creds = {ucredp->pid, ucredp->uid, ucredp->gid};