tbm_surface_internal: implement tbm_surface functions with tbm_suface_data api
[platform/core/uifw/libtbm.git] / src / tbm_drm_helper_server.c
index 2a05bf7..4be6616 100644 (file)
@@ -31,15 +31,10 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 #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"
 
@@ -54,10 +49,13 @@ struct wayland_tbm_drm_auth_server {
        uint32_t flags;
 };
 
-#define MIN(x,y) (((x)<(y))?(x):(y))
+#define MIN(x, y) (((x) < (y)) ? (x) : (y))
 
 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_auth_server *tbm_drm_auth_srv,
                       struct wl_resource *resource)
@@ -70,12 +68,16 @@ _send_server_auth_info(struct wayland_tbm_drm_auth_server *tbm_drm_auth_srv,
        fd = open(tbm_drm_auth_srv->device_name, O_RDWR | O_CLOEXEC);
        if (fd == -1 && errno == EINVAL) {
                fd = open(tbm_drm_auth_srv->device_name, O_RDWR);
-               if (fd != -1)
-                       fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
+               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_auth_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_AUTH_ERROR_AUTHENTICATE_FAIL,
                                       "authenicate failed::open_drm");
@@ -84,7 +86,7 @@ _send_server_auth_info(struct wayland_tbm_drm_auth_server *tbm_drm_auth_srv,
 
        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_AUTH_ERROR_AUTHENTICATE_FAIL,
                                               "authenicate failed::get_magic");
@@ -93,7 +95,7 @@ _send_server_auth_info(struct wayland_tbm_drm_auth_server *tbm_drm_auth_srv,
        }
 
        if (drmAuthMagic(tbm_drm_auth_srv->fd, magic) < 0) {
-               TBM_LOG("failed to authenticate magic\n");
+               TBM_ERR("failed to authenticate magic\n");
 
                wl_resource_post_error(resource, WL_TBM_DRM_AUTH_ERROR_AUTHENTICATE_FAIL,
                                       "authenicate failed::auth_magic");
@@ -149,8 +151,104 @@ _wayland_tbm_drm_auth_server_bind_cb(struct wl_client *client, void *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_auth_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_auth_srv) {
                TBM_RETURN_VAL_IF_FAIL(wl_display != NULL, 0);
@@ -159,12 +257,20 @@ tbm_drm_helper_wl_auth_server_init(void *wl_display,   int fd, const char *devic
                TBM_RETURN_VAL_IF_FAIL(tbm_drm_auth_srv != NULL, 0);
 
                tbm_drm_auth_srv->display = (struct wl_display *)wl_display;
-               tbm_drm_auth_srv->device_name = strdup(device_name);
+               if (!device_name) {
+                       tbm_drm_auth_srv->device_name = drmGetDeviceNameFromFd(fd);
+                       if (!tbm_drm_auth_srv->device_name) {
+                                       TBM_ERR("fail to get device name!\n");
+                                       return 0;
+                       }
+               } else {
+                       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_auth_srv->display, "tbm-drm-auth")) {
-                       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_auth_srv->device_name)
                                free(tbm_drm_auth_srv->device_name);
@@ -175,6 +281,8 @@ tbm_drm_helper_wl_auth_server_init(void *wl_display,   int fd, const char *devic
                        return 0;
                }
 
+               _tbm_drm_auth_socket_init(tbm_drm_auth_srv);
+
                /* init the client resource list */
                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);
@@ -200,36 +308,65 @@ tbm_drm_helper_wl_auth_server_deinit(void)
 int
 tbm_drm_helper_get_master_fd(void)
 {
-    const char *value;
-    int ret, fd = -1;
+       int new_fd, flags, fd = -1;
 
-    value = (const char*)getenv("TIZEN_DRM_MASTER_FD");
-    if (!value)
-        return -1;
+       fd = tbm_drm_master_fd;
+       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 */
+