[PATCH 1/5] server: Add new api for add socket for fd

Bryce Harrington bryce at osg.samsung.com
Thu Nov 19 01:36:21 PST 2015


From: Sangjin Lee <lsj119 at samsung.com>

Currently the server can add a socket by name.  To support an embedded
compositor in a Simplified Mandatory Access Control Kernel (Smack)
enabled environment, the embedded compositor should use the socket that
it gets from the system or session compositor.

Signed-off-by: Sangjin Lee <lsj119 at samsung.com>
Acked-by: Sung-Jin Park <sj76.park at samsung.com>
Reviewed-by: Bryce Harrington <bryce at osg.samsung.com>

---
 src/wayland-os.c          | 12 ++++++++
 src/wayland-os.h          |  2 ++
 src/wayland-server-core.h |  6 ++++
 src/wayland-server.c      | 76 ++++++++++++++++++++++++++++++-----------------
 4 files changed, 68 insertions(+), 28 deletions(-)

diff --git a/src/wayland-os.c b/src/wayland-os.c
index 93b6f5f..31114f6 100644
--- a/src/wayland-os.c
+++ b/src/wayland-os.c
@@ -27,6 +27,7 @@
 
 #include <sys/types.h>
 #include <sys/socket.h>
+#include <sys/stat.h>
 #include <unistd.h>
 #include <fcntl.h>
 #include <errno.h>
@@ -73,6 +74,17 @@ wl_os_socket_cloexec(int domain, int type, int protocol)
 }
 
 int
+wl_os_socket_check_cloexec(int fd)
+{
+	struct stat buf;
+
+	if (fd < 0 || fstat(fd, &buf) < 0 || !S_ISSOCK(buf.st_mode))
+		return -1;
+
+	return set_cloexec_or_close(fd);
+}
+
+int
 wl_os_dupfd_cloexec(int fd, long minfd)
 {
 	int newfd;
diff --git a/src/wayland-os.h b/src/wayland-os.h
index f51efaa..e3e7bf0 100644
--- a/src/wayland-os.h
+++ b/src/wayland-os.h
@@ -41,6 +41,8 @@ wl_os_epoll_create_cloexec(void);
 int
 wl_os_accept_cloexec(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
 
+int
+wl_os_socket_check_cloexec(int fd);
 
 /*
  * The following are for wayland-os.c and the unit tests.
diff --git a/src/wayland-server-core.h b/src/wayland-server-core.h
index 85b4b9e..9710609 100644
--- a/src/wayland-server-core.h
+++ b/src/wayland-server-core.h
@@ -128,9 +128,15 @@ wl_display_get_event_loop(struct wl_display *display);
 int
 wl_display_add_socket(struct wl_display *display, const char *name);
 
+int
+wl_display_add_socket_fd(struct wl_display *display, const char *name, int sock_fd);
+
 const char *
 wl_display_add_socket_auto(struct wl_display *display);
 
+const char *
+wl_display_add_socket_fd_auto(struct wl_display *display, int sock_fd);
+
 void
 wl_display_terminate(struct wl_display *display);
 
diff --git a/src/wayland-server.c b/src/wayland-server.c
index 0f04f66..bac98bf 100644
--- a/src/wayland-server.c
+++ b/src/wayland-server.c
@@ -1133,8 +1133,12 @@ _wl_display_add_socket(struct wl_display *display, struct wl_socket *s)
 {
 	socklen_t size;
 
-	s->fd = wl_os_socket_cloexec(PF_LOCAL, SOCK_STREAM, 0);
-	if (s->fd < 0) {
+	if (s->fd == -1) {
+		s->fd = wl_os_socket_cloexec(PF_LOCAL, SOCK_STREAM, 0);
+		if (s->fd < 0) {
+			return -1;
+		}
+	} else if (wl_os_socket_check_cloexec(s->fd) < 0) {
 		return -1;
 	}
 
@@ -1161,7 +1165,7 @@ _wl_display_add_socket(struct wl_display *display, struct wl_socket *s)
 }
 
 WL_EXPORT const char *
-wl_display_add_socket_auto(struct wl_display *display)
+wl_display_add_socket_fd_auto(struct wl_display *display, int sock_fd)
 {
 	struct wl_socket *s;
 	int displayno = 0;
@@ -1185,6 +1189,8 @@ wl_display_add_socket_auto(struct wl_display *display)
 		if (wl_socket_lock(s) < 0)
 			continue;
 
+		s->fd = sock_fd;
+
 		if (_wl_display_add_socket(display, s) < 0) {
 			wl_socket_destroy(s);
 			return NULL;
@@ -1199,32 +1205,14 @@ wl_display_add_socket_auto(struct wl_display *display)
 	return NULL;
 }
 
-/** Add a socket to Wayland display for the clients to connect.
- *
- * \param display Wayland display to which the socket should be added.
- * \param name Name of the Unix socket.
- * \return 0 if success. -1 if failed.
- *
- * This adds a Unix socket to Wayland display which can be used by clients to
- * connect to Wayland display.
- *
- * If NULL is passed as name, then it would look for WAYLAND_DISPLAY env
- * variable for the socket name. If WAYLAND_DISPLAY is not set, then default
- * wayland-0 is used.
- *
- * The Unix socket will be created in the directory pointed to by environment
- * variable XDG_RUNTIME_DIR. If XDG_RUNTIME_DIR is not set, then this function
- * fails and returns -1.
- *
- * The length of socket path, i.e., the path set in XDG_RUNTIME_DIR and the
- * socket name, must not exceed the maxium length of a Unix socket path.
- * The function also fails if the user do not have write permission in the
- * XDG_RUNTIME_DIR path or if the socket name is already in use.
- *
- * \memberof wl_display
- */
+WL_EXPORT const char *
+wl_display_add_socket_auto(struct wl_display *display)
+{
+	return wl_display_add_socket_fd_auto(display, -1);
+}
+
 WL_EXPORT int
-wl_display_add_socket(struct wl_display *display, const char *name)
+wl_display_add_socket_fd(struct wl_display *display, const char *name, int sock_fd)
 {
 	struct wl_socket *s;
 
@@ -1247,6 +1235,8 @@ wl_display_add_socket(struct wl_display *display, const char *name)
 		return -1;
 	}
 
+	s->fd = sock_fd;
+
 	if (_wl_display_add_socket(display, s) < 0) {
 		wl_socket_destroy(s);
 		return -1;
@@ -1255,6 +1245,36 @@ wl_display_add_socket(struct wl_display *display, const char *name)
 	return 0;
 }
 
+/** Add a socket to Wayland display for the clients to connect.
+ *
+ * \param display Wayland display to which the socket should be added.
+ * \param name Name of the Unix socket.
+ * \return 0 if success. -1 if failed.
+ *
+ * This adds a Unix socket to Wayland display which can be used by clients to
+ * connect to Wayland display.
+ *
+ * If NULL is passed as name, then it would look for WAYLAND_DISPLAY env
+ * variable for the socket name. If WAYLAND_DISPLAY is not set, then default
+ * wayland-0 is used.
+ *
+ * The Unix socket will be created in the directory pointed to by environment
+ * variable XDG_RUNTIME_DIR. If XDG_RUNTIME_DIR is not set, then this function
+ * fails and returns -1.
+ *
+ * The length of socket path, i.e., the path set in XDG_RUNTIME_DIR and the
+ * socket name, must not exceed the maxium length of a Unix socket path.
+ * The function also fails if the user do not have write permission in the
+ * XDG_RUNTIME_DIR path or if the socket name is already in use.
+ *
+ * \memberof wl_display
+ */
+WL_EXPORT int
+wl_display_add_socket(struct wl_display *display, const char *name)
+{
+	return wl_display_add_socket_fd(display, name, -1);
+}
+
 WL_EXPORT void
 wl_display_add_destroy_listener(struct wl_display *display,
 				struct wl_listener *listener)
-- 
1.9.1



More information about the wayland-devel mailing list