#define WL_HIDE_DEPRECATED
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stddef.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
+#include "config.h"
#include <xf86drm.h>
+#include <grp.h>
#include "tbm_bufmgr_int.h"
-#include "wayland-tbm-drm-server-protocol.h"
+#include "wayland-tbm-drm-auth-server-protocol.h"
-struct wayland_tbm_drm_server {
+struct wayland_tbm_drm_auth_server {
struct wl_display *display;
- struct wl_global *wl_tbm_drm_global;
+ struct wl_global *wl_tbm_drm_auth_global;
char *device_name;
uint32_t fd;
uint32_t flags;
};
-#define MIN(x,y) (((x)<(y))?(x):(y))
+#define MIN(x, y) (((x) < (y)) ? (x) : (y))
-struct wayland_tbm_drm_server *tbm_drm_srv;
+struct wayland_tbm_drm_auth_server *tbm_drm_auth_srv;
+static int tbm_drm_master_fd = -1;
+
+/* LCOV_EXCL_START */
static void
-_send_server_auth_info(struct wayland_tbm_drm_server *tbm_drm_srv,
+_send_server_auth_info(struct wayland_tbm_drm_auth_server *tbm_drm_auth_srv,
struct wl_resource *resource)
{
int fd = -1;
char *device_name = NULL;
drm_magic_t magic = 0;
- fd = open(tbm_drm_srv->device_name, O_RDWR | O_CLOEXEC);
+ fd = open(tbm_drm_auth_srv->device_name, O_RDWR | O_CLOEXEC);
if (fd == -1 && errno == EINVAL) {
- fd = open(tbm_drm_srv->device_name, O_RDWR);
- if (fd != -1)
- fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
+ fd = open(tbm_drm_auth_srv->device_name, O_RDWR);
+ if (fd != -1) {
+ if (fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC) == -1) {
+ TBM_ERR("failed to set fd\n");
+ goto fini;
+ }
+ }
}
if (fd < 0) {
- TBM_LOG("failed to open drm : device_name, %s\n", tbm_drm_srv->device_name);
+ TBM_ERR("failed to open drm : device_name, %s\n", tbm_drm_auth_srv->device_name);
- wl_resource_post_error(resource, WL_TBM_DRM_ERROR_AUTHENTICATE_FAIL,
+ wl_resource_post_error(resource, WL_TBM_DRM_AUTH_ERROR_AUTHENTICATE_FAIL,
"authenicate failed::open_drm");
goto fini;
}
if (drmGetMagic(fd, &magic) < 0) {
if (errno != EACCES) {
- TBM_LOG("failed to get magic\n");
+ TBM_ERR("failed to get magic\n");
- wl_resource_post_error(resource, WL_TBM_DRM_ERROR_AUTHENTICATE_FAIL,
+ wl_resource_post_error(resource, WL_TBM_DRM_AUTH_ERROR_AUTHENTICATE_FAIL,
"authenicate failed::get_magic");
goto fini;
}
}
- if (drmAuthMagic(tbm_drm_srv->fd, magic) < 0) {
- TBM_LOG("failed to authenticate magic\n");
+ if (drmAuthMagic(tbm_drm_auth_srv->fd, magic) < 0) {
+ TBM_ERR("failed to authenticate magic\n");
- wl_resource_post_error(resource, WL_TBM_DRM_ERROR_AUTHENTICATE_FAIL,
+ wl_resource_post_error(resource, WL_TBM_DRM_AUTH_ERROR_AUTHENTICATE_FAIL,
"authenicate failed::auth_magic");
goto fini;
}
- capabilities = tbm_drm_srv->flags;
- device_name = tbm_drm_srv->device_name;
+ capabilities = tbm_drm_auth_srv->flags;
+ device_name = tbm_drm_auth_srv->device_name;
/* send */
- wl_tbm_drm_send_authentication_info(resource, device_name, capabilities, fd);
+ wl_tbm_drm_auth_send_authentication_info(resource, device_name, capabilities, fd);
fini:
if (fd >= 0)
close(fd);
- if (device_name && device_name != tbm_drm_srv->device_name)
+ if (device_name && device_name != tbm_drm_auth_srv->device_name)
free(device_name);
}
static void
-_wayland_tbm_drm_server_impl_get_authentication_info(struct wl_client *client,
+_wayland_tbm_drm_auth_server_impl_get_authentication_info(struct wl_client *client,
struct wl_resource *resource)
{
- struct wayland_tbm_drm_server *tbm_drm_srv = wl_resource_get_user_data(resource);
+ struct wayland_tbm_drm_auth_server *tbm_drm_auth_srv = wl_resource_get_user_data(resource);
/* if display server is the client of the host display server, for embedded server */
- _send_server_auth_info(tbm_drm_srv, resource);
+ _send_server_auth_info(tbm_drm_auth_srv, resource);
}
-static const struct wl_tbm_drm_interface _wayland_tbm_drm_server_implementation = {
- _wayland_tbm_drm_server_impl_get_authentication_info,
+static const struct wl_tbm_drm_auth_interface _wayland_tbm_drm_auth_server_implementation = {
+ _wayland_tbm_drm_auth_server_impl_get_authentication_info,
};
static void
-_wayland_tbm_drm_server_bind_cb(struct wl_client *client, void *data,
+_wayland_tbm_drm_auth_server_bind_cb(struct wl_client *client, void *data,
uint32_t version,
uint32_t id)
{
struct wl_resource *resource;
- resource = wl_resource_create(client, &wl_tbm_drm_interface, MIN(version, 1), id);
+ resource = wl_resource_create(client, &wl_tbm_drm_auth_interface, MIN(version, 1), id);
if (!resource) {
wl_client_post_no_memory(client);
return;
}
wl_resource_set_implementation(resource,
- &_wayland_tbm_drm_server_implementation,
+ &_wayland_tbm_drm_auth_server_implementation,
data,
NULL);
}
+static int
+_tbm_getgrnam_r(const char *name)
+{
+ struct group *grp = NULL;
+ struct group *grp_res = NULL;
+ char* buf = NULL;
+ size_t buf_len;
+ int ret;
+ int id;
+
+ buf_len = sysconf(_SC_GETGR_R_SIZE_MAX);
+ if (buf_len == -1)
+ buf_len = 2048;
+
+ buf = calloc(1, buf_len * sizeof(char));
+ if (!buf) {
+ TBM_ERR("creating buffer failed\n");
+ goto failed;
+ }
+
+ grp = calloc(1, sizeof(struct group));
+ if (!grp) {
+ TBM_ERR("creating group failed\n");
+ goto failed;
+ }
+
+ ret = getgrnam_r(name, grp, buf, buf_len, &grp_res);
+ if (ret < 0) {
+ TBM_ERR("getgrnam_r failed errno:%d(%m)\n", ret);
+ goto failed;
+ }
+
+ if (grp_res == NULL) {
+ TBM_ERR("finding name:%s group failed\n", name);
+ goto failed;
+ }
+
+ id = grp->gr_gid;
+ free(buf);
+ free(grp);
+
+ return id;
+
+failed:
+ if (buf)
+ free(buf);
+ if (grp)
+ free(grp);
+
+ return -1;
+}
+
+static void
+_tbm_drm_auth_socket_init(struct wayland_tbm_drm_auth_server *tbm_drm_auth_srv)
+{
+ const char *dir = NULL;
+ char socket_path[128];
+ int ret = -1;
+ uid_t uid;
+ gid_t gid;
+
+ dir = getenv("XDG_RUNTIME_DIR");
+ if (!dir) {
+ TBM_WRN("getting XDG_RUNTIME_DIR failed\n");
+ return;
+ }
+
+ snprintf(socket_path, sizeof(socket_path), "%s/%s", dir, "tbm-drm-auth");
+
+ ret = chmod(socket_path, 509);
+ if (ret < 0) {
+ TBM_WRN("changing modes of socket file failed:%s (%m)\n", socket_path);
+ return;
+ }
+
+ ret = _tbm_getgrnam_r("root");
+ if (ret < 0) {
+ TBM_WRN("getting uid failed\n");
+ return;
+ }
+ uid = ret;
+
+ ret = _tbm_getgrnam_r("display");
+ if (ret < 0) {
+ TBM_WRN("getting gid failed\n");
+ return;
+ }
+ gid = ret;
+
+ ret = chown(socket_path, uid, gid);
+ if (ret < 0) {
+ TBM_WRN("changing owner of socket file failed:%s (%m)\n", socket_path);
+ return;
+ }
+}
+
int
-tbm_drm_helper_wl_server_init(void *wl_display, int fd, const char *device_name, uint32_t flags)
+tbm_drm_helper_wl_auth_server_init(void *wl_display, int fd, const char *device_name, uint32_t flags)
{
- if (!tbm_drm_srv) {
+ if (!tbm_drm_auth_srv) {
TBM_RETURN_VAL_IF_FAIL(wl_display != NULL, 0);
- tbm_drm_srv = calloc(1, sizeof(struct wayland_tbm_drm_server));
- TBM_RETURN_VAL_IF_FAIL(tbm_drm_srv != NULL, 0);
+ tbm_drm_auth_srv = calloc(1, sizeof(struct wayland_tbm_drm_auth_server));
+ TBM_RETURN_VAL_IF_FAIL(tbm_drm_auth_srv != NULL, 0);
- tbm_drm_srv->display = (struct wl_display *)wl_display;
- tbm_drm_srv->device_name = strdup(device_name);
- tbm_drm_srv->fd = fd;
- tbm_drm_srv->flags = flags;
+ tbm_drm_auth_srv->display = (struct wl_display *)wl_display;
+ tbm_drm_auth_srv->device_name = strdup(device_name);
+ tbm_drm_auth_srv->fd = fd;
+ tbm_drm_auth_srv->flags = flags;
- if(wl_display_add_socket(tbm_drm_srv->display, "tbm_drm")) {
- TBM_LOG("[TBM_DRM] fail to add socket\n");
+ if (wl_display_add_socket(tbm_drm_auth_srv->display, "tbm-drm-auth")) {
+ TBM_ERR("[TBM_DRM] fail to add socket\n");
- if (tbm_drm_srv->device_name)
- free(tbm_drm_srv->device_name);
+ if (tbm_drm_auth_srv->device_name)
+ free(tbm_drm_auth_srv->device_name);
- free(tbm_drm_srv);
- tbm_drm_srv = NULL;
+ free(tbm_drm_auth_srv);
+ tbm_drm_auth_srv = NULL;
return 0;
}
+ _tbm_drm_auth_socket_init(tbm_drm_auth_srv);
+
/* init the client resource list */
- tbm_drm_srv->wl_tbm_drm_global = wl_global_create(tbm_drm_srv->display, &wl_tbm_drm_interface, 1,
- tbm_drm_srv, _wayland_tbm_drm_server_bind_cb);
+ tbm_drm_auth_srv->wl_tbm_drm_auth_global = wl_global_create(tbm_drm_auth_srv->display, &wl_tbm_drm_auth_interface, 1,
+ tbm_drm_auth_srv, _wayland_tbm_drm_auth_server_bind_cb);
}
return 1;
}
void
-tbm_drm_helper_wl_server_deinit(void)
+tbm_drm_helper_wl_auth_server_deinit(void)
{
- if (tbm_drm_srv) {
- wl_global_destroy(tbm_drm_srv->wl_tbm_drm_global);
+ if (tbm_drm_auth_srv) {
+ wl_global_destroy(tbm_drm_auth_srv->wl_tbm_drm_auth_global);
- if (tbm_drm_srv->device_name)
- free(tbm_drm_srv->device_name);
+ if (tbm_drm_auth_srv->device_name)
+ free(tbm_drm_auth_srv->device_name);
- free(tbm_drm_srv);
- tbm_drm_srv = NULL;
+ free(tbm_drm_auth_srv);
+ tbm_drm_auth_srv = NULL;
}
}
int
tbm_drm_helper_get_master_fd(void)
{
- const char *value;
- int ret, fd = -1;
+ int new_fd, flags, fd = -1;
+
+#if 1 /* TODO: can't remove below at this time. This code SHOULD be removed later */
+ const char *value = (const char*)getenv("TDM_DRM_MASTER_FD");
+ if (value) {
+ char *end;
+ const long int sl = strtol(value, &end, 10);
+
+ if (end == value) {
+ TBM_ERR("%s: not a decimal number\n", value);
+ return -1;
+ } else if (*end != '\0') {
+ TBM_ERR("%s: extra characters at end of input: %s\n", value, end);
+ return -1;
+ } else if ((sl == LONG_MIN || sl == LONG_MAX) && errno == ERANGE) {
+ TBM_ERR("%s out of range of type long\n", value);
+ return -1;
+ } else if (sl >= INT_MAX) {
+ TBM_ERR("%ld greater than INT_MAX\n", sl);
+ return -1;
+ } else if (sl <= INT_MIN) {
+ TBM_ERR("%ld less than INT_MIN\n", sl);
+ return -1;
+ } else {
+ int fd_max = tbm_bufmgr_get_fd_limit();
+ fd = (int)sl;
+ if (fd < 0 || fd > fd_max) {
+ TBM_ERR("%d out of fd range\n", fd);
+ return -1;
+ }
+ }
+ } else
+#endif
+ fd = tbm_drm_master_fd;
- value = (const char*)getenv("TIZEN_DRM_MASTER_FD");
- if (!value)
- return -1;
+ if (fd == -1) {
+ TBM_INFO("no presetted TBM DRM MASTER FD");
+ return -1;
+ }
- ret = sscanf(value, "%d", &fd);
- if (ret <= 0)
- return -1;
+ TBM_INFO("TBM DRM MASTER FD: %d\n", fd);
- TBM_LOG("TIZEN_DRM_MASTER_FD: %d", fd);
+ flags = fcntl(fd, F_GETFD);
+ if (flags == -1) {
+ TBM_ERR("fcntl failed: %m");
+ return -1;
+ }
+
+ new_fd = dup(fd);
+ if (new_fd < 0) {
+ TBM_ERR("dup failed: %m");
+ return -1;
+ }
- return fd;
+ if (fcntl(new_fd, F_SETFD, flags|FD_CLOEXEC) == -1) {
+ TBM_ERR("failed to set fd\n");
+ close(new_fd);
+ return -1;
+ }
+
+ TBM_INFO("Return MASTER_FD: %d\n", new_fd);
+
+ return new_fd;
}
void
-tbm_drm_helper_set_master_fd(int fd)
+tbm_drm_helper_set_tbm_master_fd(int fd)
{
- char buf[32];
- int ret;
+ int fd_max = tbm_bufmgr_get_fd_limit();
- snprintf(buf, sizeof(buf), "%d", fd);
+ if (tbm_drm_master_fd == fd)
+ return;
+
+ if (fd < 0 || fd > fd_max) {
+ TBM_ERR("%d out of fd range\n", fd);
+ return;
+ }
- ret = setenv("TIZEN_DRM_MASTER_FD", (const char*)buf, 1);
- if (ret)
- {
- TBM_LOG("failed to set TIZEN_DRM_MASTER_FD to %d", fd);
- return;
- }
+ if (tbm_drm_master_fd != -1)
+ TBM_WRN("already has TBM DRM MASTER FD: %d\n", tbm_drm_master_fd);
- TBM_LOG("TIZEN_DRM_MASTER_FD: %d", fd);
+ tbm_drm_master_fd = fd;
+
+ TBM_INFO("TBM DRM MASTER FD: %d\n", tbm_drm_master_fd);
+}
+
+void
+tbm_drm_helper_unset_tbm_master_fd(void)
+{
+ tbm_drm_master_fd = -1;
+ TBM_INFO("TBM DRM MASTER FD: %d\n", tbm_drm_master_fd);
}
+/* LCOV_EXCL_STOP */
+