blob: 75e7051f6742aecc8a5fadd61122459e53d3636a [file] [log] [blame]
Benjamin Franzkebfeda132012-01-30 14:04:04 +01001/*
2 * Copyright © 2012 Benjamin Franzke
Kristian Høgsberg05ad1e42013-09-17 14:41:03 -07003 * Copyright © 2013 Intel Corporation
Benjamin Franzkebfeda132012-01-30 14:04:04 +01004 *
5 * Permission to use, copy, modify, distribute, and sell this software and
6 * its documentation for any purpose is hereby granted without fee, provided
7 * that the above copyright notice appear in all copies and that both that
8 * copyright notice and this permission notice appear in supporting
9 * documentation, and that the name of the copyright holders not be used in
10 * advertising or publicity pertaining to distribution of the software
11 * without specific, written prior permission. The copyright holders make
12 * no representations about the suitability of this software for any
13 * purpose. It is provided "as is" without express or implied warranty.
14 *
15 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
16 * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17 * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
18 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
19 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
20 * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
21 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22 */
23
Daniel Stonec228e232013-05-22 18:03:19 +030024#include "config.h"
25
Benjamin Franzkebfeda132012-01-30 14:04:04 +010026#include <stdio.h>
27#include <stdlib.h>
28#include <string.h>
29
30#include <errno.h>
31#include <sys/socket.h>
32#include <sys/types.h>
33#include <sys/stat.h>
34#include <sys/uio.h>
35#include <fcntl.h>
Kristian Høgsberg05ad1e42013-09-17 14:41:03 -070036#include <unistd.h>
Benjamin Franzkebfeda132012-01-30 14:04:04 +010037
38#include <xf86drm.h>
39
40#include "compositor.h"
41#include "launcher-util.h"
42#include "weston-launch.h"
43
Kristian Høgsberg9e140912012-04-10 01:26:18 -040044union cmsg_data { unsigned char b[4]; int fd; };
45
Kristian Høgsberg05ad1e42013-09-17 14:41:03 -070046struct weston_launcher {
47 struct weston_compositor *compositor;
48 int fd;
Kristian Høgsberg1eb482d2013-09-17 22:15:37 -070049 struct wl_event_source *source;
Kristian Høgsberg05ad1e42013-09-17 14:41:03 -070050};
51
Benjamin Franzkebfeda132012-01-30 14:04:04 +010052int
Kristian Høgsberg05ad1e42013-09-17 14:41:03 -070053weston_launcher_open(struct weston_launcher *launcher,
Benjamin Franzkebfeda132012-01-30 14:04:04 +010054 const char *path, int flags)
55{
Kristian Høgsberg9e140912012-04-10 01:26:18 -040056 int n, ret = -1;
Benjamin Franzkebfeda132012-01-30 14:04:04 +010057 struct msghdr msg;
58 struct cmsghdr *cmsg;
59 struct iovec iov;
Kristian Høgsberg9e140912012-04-10 01:26:18 -040060 union cmsg_data *data;
61 char control[CMSG_SPACE(sizeof data->fd)];
Benjamin Franzkebfeda132012-01-30 14:04:04 +010062 ssize_t len;
63 struct weston_launcher_open *message;
64
Kristian Høgsberg05ad1e42013-09-17 14:41:03 -070065 if (launcher == NULL)
Pekka Paalanen27979b02012-07-31 13:21:06 +030066 return open(path, flags | O_CLOEXEC);
Benjamin Franzkebfeda132012-01-30 14:04:04 +010067
68 n = sizeof(*message) + strlen(path) + 1;
69 message = malloc(n);
70 if (!message)
71 return -1;
72
73 message->header.opcode = WESTON_LAUNCHER_OPEN;
74 message->flags = flags;
75 strcpy(message->path, path);
76
77 do {
Kristian Høgsberg05ad1e42013-09-17 14:41:03 -070078 len = send(launcher->fd, message, n, 0);
Benjamin Franzkebfeda132012-01-30 14:04:04 +010079 } while (len < 0 && errno == EINTR);
Kristian Høgsbergba25bd72012-04-10 01:31:09 -040080 free(message);
Benjamin Franzkebfeda132012-01-30 14:04:04 +010081
82 memset(&msg, 0, sizeof msg);
83 iov.iov_base = &ret;
84 iov.iov_len = sizeof ret;
85 msg.msg_iov = &iov;
86 msg.msg_iovlen = 1;
87 msg.msg_control = control;
88 msg.msg_controllen = sizeof control;
89
90 do {
Kristian Høgsberg05ad1e42013-09-17 14:41:03 -070091 len = recvmsg(launcher->fd, &msg, MSG_CMSG_CLOEXEC);
Benjamin Franzkebfeda132012-01-30 14:04:04 +010092 } while (len < 0 && errno == EINTR);
93
94 if (len != sizeof ret ||
95 ret < 0)
Kristian Høgsbergba25bd72012-04-10 01:31:09 -040096 return -1;
Benjamin Franzkebfeda132012-01-30 14:04:04 +010097
98 cmsg = CMSG_FIRSTHDR(&msg);
99 if (!cmsg ||
100 cmsg->cmsg_level != SOL_SOCKET ||
101 cmsg->cmsg_type != SCM_RIGHTS) {
102 fprintf(stderr, "invalid control message\n");
Kristian Høgsbergba25bd72012-04-10 01:31:09 -0400103 return -1;
Benjamin Franzkebfeda132012-01-30 14:04:04 +0100104 }
105
Kristian Høgsberg9e140912012-04-10 01:26:18 -0400106 data = (union cmsg_data *) CMSG_DATA(cmsg);
107 if (data->fd == -1) {
Martin Andersson566b4642013-02-13 00:11:12 +0100108 fprintf(stderr, "missing drm fd in socket request\n");
Benjamin Franzkebfeda132012-01-30 14:04:04 +0100109 return -1;
110 }
111
Kristian Høgsbergba25bd72012-04-10 01:31:09 -0400112 return data->fd;
Benjamin Franzkebfeda132012-01-30 14:04:04 +0100113}
114
Kristian Høgsberg1eb482d2013-09-17 22:15:37 -0700115static int
116weston_launcher_data(int fd, uint32_t mask, void *data)
Benjamin Franzkebfeda132012-01-30 14:04:04 +0100117{
Kristian Høgsberg1eb482d2013-09-17 22:15:37 -0700118 struct weston_launcher *launcher = data;
119 int len, ret;
Benjamin Franzkebfeda132012-01-30 14:04:04 +0100120
Kristian Høgsberg1eb482d2013-09-17 22:15:37 -0700121 if (mask & (WL_EVENT_HANGUP | WL_EVENT_ERROR)) {
122 weston_log("launcher socket closed, exiting\n");
123 exit(-1);
Benjamin Franzkebfeda132012-01-30 14:04:04 +0100124 }
125
Benjamin Franzkebfeda132012-01-30 14:04:04 +0100126 do {
Kristian Høgsberg05ad1e42013-09-17 14:41:03 -0700127 len = recv(launcher->fd, &ret, sizeof ret, 0);
Benjamin Franzkebfeda132012-01-30 14:04:04 +0100128 } while (len < 0 && errno == EINTR);
Benjamin Franzkebfeda132012-01-30 14:04:04 +0100129
Kristian Høgsberg1eb482d2013-09-17 22:15:37 -0700130 switch (ret) {
131 case WESTON_LAUNCHER_ACTIVATE:
132 launcher->compositor->session_active = 1;
133 wl_signal_emit(&launcher->compositor->session_signal,
134 launcher->compositor);
135 break;
136 case WESTON_LAUNCHER_DEACTIVATE:
137 launcher->compositor->session_active = 0;
138 wl_signal_emit(&launcher->compositor->session_signal,
139 launcher->compositor);
140 break;
141 default:
142 weston_log("unexpected event from weston-launch\n");
143 break;
144 }
145
146 return 1;
Benjamin Franzkebfeda132012-01-30 14:04:04 +0100147}
148
Kristian Høgsberg05ad1e42013-09-17 14:41:03 -0700149struct weston_launcher *
150weston_launcher_connect(struct weston_compositor *compositor)
151{
152 struct weston_launcher *launcher;
Kristian Høgsberg1eb482d2013-09-17 22:15:37 -0700153 struct wl_event_loop *loop;
Kristian Høgsberg05ad1e42013-09-17 14:41:03 -0700154 int fd;
155
156 fd = weston_environment_get_fd("WESTON_LAUNCHER_SOCK");
157 if (fd == -1)
158 return NULL;
159
160 launcher = malloc(sizeof *launcher);
161 if (launcher == NULL)
162 return NULL;
163
164 launcher->compositor = compositor;
165 launcher->fd = fd;
166
Kristian Høgsberg1eb482d2013-09-17 22:15:37 -0700167 loop = wl_display_get_event_loop(compositor->wl_display);
168 launcher->source = wl_event_loop_add_fd(loop, launcher->fd,
169 WL_EVENT_READABLE,
170 weston_launcher_data,
171 launcher);
172 if (launcher->source == NULL) {
173 free(launcher);
174 return NULL;
175 }
176
Kristian Høgsberg05ad1e42013-09-17 14:41:03 -0700177 return launcher;
178}
179
180void
181weston_launcher_destroy(struct weston_launcher *launcher)
182{
183 close(launcher->fd);
184 free(launcher);
185}