blob: 6f6ee116cdaad201253b5f945c68b9875289e91b [file] [log] [blame]
Benjamin Franzkebfeda132012-01-30 14:04:04 +01001/*
2 * Copyright © 2012 Benjamin Franzke
3 *
4 * Permission to use, copy, modify, distribute, and sell this software and
5 * its documentation for any purpose is hereby granted without fee, provided
6 * that the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation, and that the name of the copyright holders not be used in
9 * advertising or publicity pertaining to distribution of the software
10 * without specific, written prior permission. The copyright holders make
11 * no representations about the suitability of this software for any
12 * purpose. It is provided "as is" without express or implied warranty.
13 *
14 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
15 * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
16 * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
17 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
18 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
19 * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
20 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21 */
22
Daniel Stonec228e232013-05-22 18:03:19 +030023#include "config.h"
24
Benjamin Franzkebfeda132012-01-30 14:04:04 +010025#include <stdio.h>
26#include <stdlib.h>
27#include <string.h>
28
29#include <errno.h>
30#include <sys/socket.h>
31#include <sys/types.h>
32#include <sys/stat.h>
33#include <sys/uio.h>
34#include <fcntl.h>
35
36#include <xf86drm.h>
37
38#include "compositor.h"
39#include "launcher-util.h"
40#include "weston-launch.h"
41
Kristian Høgsberg9e140912012-04-10 01:26:18 -040042union cmsg_data { unsigned char b[4]; int fd; };
43
Benjamin Franzkebfeda132012-01-30 14:04:04 +010044int
45weston_launcher_open(struct weston_compositor *compositor,
46 const char *path, int flags)
47{
48 int sock = compositor->launcher_sock;
Kristian Høgsberg9e140912012-04-10 01:26:18 -040049 int n, ret = -1;
Benjamin Franzkebfeda132012-01-30 14:04:04 +010050 struct msghdr msg;
51 struct cmsghdr *cmsg;
52 struct iovec iov;
Kristian Høgsberg9e140912012-04-10 01:26:18 -040053 union cmsg_data *data;
54 char control[CMSG_SPACE(sizeof data->fd)];
Benjamin Franzkebfeda132012-01-30 14:04:04 +010055 ssize_t len;
56 struct weston_launcher_open *message;
57
58 if (sock == -1)
Pekka Paalanen27979b02012-07-31 13:21:06 +030059 return open(path, flags | O_CLOEXEC);
Benjamin Franzkebfeda132012-01-30 14:04:04 +010060
61 n = sizeof(*message) + strlen(path) + 1;
62 message = malloc(n);
63 if (!message)
64 return -1;
65
66 message->header.opcode = WESTON_LAUNCHER_OPEN;
67 message->flags = flags;
68 strcpy(message->path, path);
69
70 do {
71 len = send(sock, message, n, 0);
72 } while (len < 0 && errno == EINTR);
Kristian Høgsbergba25bd72012-04-10 01:31:09 -040073 free(message);
Benjamin Franzkebfeda132012-01-30 14:04:04 +010074
75 memset(&msg, 0, sizeof msg);
76 iov.iov_base = &ret;
77 iov.iov_len = sizeof ret;
78 msg.msg_iov = &iov;
79 msg.msg_iovlen = 1;
80 msg.msg_control = control;
81 msg.msg_controllen = sizeof control;
82
83 do {
84 len = recvmsg(sock, &msg, MSG_CMSG_CLOEXEC);
85 } while (len < 0 && errno == EINTR);
86
87 if (len != sizeof ret ||
88 ret < 0)
Kristian Høgsbergba25bd72012-04-10 01:31:09 -040089 return -1;
Benjamin Franzkebfeda132012-01-30 14:04:04 +010090
91 cmsg = CMSG_FIRSTHDR(&msg);
92 if (!cmsg ||
93 cmsg->cmsg_level != SOL_SOCKET ||
94 cmsg->cmsg_type != SCM_RIGHTS) {
95 fprintf(stderr, "invalid control message\n");
Kristian Høgsbergba25bd72012-04-10 01:31:09 -040096 return -1;
Benjamin Franzkebfeda132012-01-30 14:04:04 +010097 }
98
Kristian Høgsberg9e140912012-04-10 01:26:18 -040099 data = (union cmsg_data *) CMSG_DATA(cmsg);
100 if (data->fd == -1) {
Martin Andersson566b4642013-02-13 00:11:12 +0100101 fprintf(stderr, "missing drm fd in socket request\n");
Benjamin Franzkebfeda132012-01-30 14:04:04 +0100102 return -1;
103 }
104
Kristian Høgsbergba25bd72012-04-10 01:31:09 -0400105 return data->fd;
Benjamin Franzkebfeda132012-01-30 14:04:04 +0100106}
107
108int
109weston_launcher_drm_set_master(struct weston_compositor *compositor,
110 int drm_fd, char master)
111{
112 struct msghdr msg;
113 struct cmsghdr *cmsg;
114 struct iovec iov;
115 char control[CMSG_SPACE(sizeof(drm_fd))];
116 int ret;
117 ssize_t len;
118 struct weston_launcher_set_master message;
Kristian Høgsberg9e140912012-04-10 01:26:18 -0400119 union cmsg_data *data;
Benjamin Franzkebfeda132012-01-30 14:04:04 +0100120
121 if (compositor->launcher_sock == -1) {
122 if (master)
123 return drmSetMaster(drm_fd);
124 else
125 return drmDropMaster(drm_fd);
126 }
127
128 memset(&msg, 0, sizeof msg);
129 msg.msg_iov = &iov;
130 msg.msg_iovlen = 1;
131 msg.msg_control = control;
132 msg.msg_controllen = sizeof control;
133 cmsg = CMSG_FIRSTHDR(&msg);
134 cmsg->cmsg_level = SOL_SOCKET;
135 cmsg->cmsg_type = SCM_RIGHTS;
136 cmsg->cmsg_len = CMSG_LEN(sizeof(drm_fd));
137
Kristian Høgsberg9e140912012-04-10 01:26:18 -0400138 data = (union cmsg_data *) CMSG_DATA(cmsg);
139 data->fd = drm_fd;
Benjamin Franzkebfeda132012-01-30 14:04:04 +0100140 msg.msg_controllen = cmsg->cmsg_len;
141
142 iov.iov_base = &message;
143 iov.iov_len = sizeof message;
144
145 message.header.opcode = WESTON_LAUNCHER_DRM_SET_MASTER;
146 message.set_master = master;
147
148 do {
149 len = sendmsg(compositor->launcher_sock, &msg, 0);
150 } while (len < 0 && errno == EINTR);
151 if (len < 0)
152 return -1;
153
154 do {
155 len = recv(compositor->launcher_sock, &ret, sizeof ret, 0);
156 } while (len < 0 && errno == EINTR);
157 if (len < 0)
158 return -1;
159
160 return ret;
161}
162