From 06c44ede55128432378f6a607fcc2308f39e7838 Mon Sep 17 00:00:00 2001 From: Uli Schlachter Date: Tue, 29 Dec 2020 14:17:17 +0100 Subject: [PATCH] xwayland: Unlink X11 socket before binding to it When starting xwayland with smithay, the first time I would get the following output (do not ask what happens with displays 0, 1, 2. That's not important right now): Dec 29 14:13:31.031 DEBG Attempting to aquire an X11 display lock, D: 3, smithay_module: XWayland Dec 29 14:13:31.032 DEBG X11 lock aquired, D: 3, smithay_module: XWayland Dec 29 14:13:31.032 INFO Initialization completed, starting the main loop. When killing the process with ctrl-c and starting it again, this happened: Dec 29 14:13:29.138 DEBG Attempting to aquire an X11 display lock, D: 3, smithay_module: XWayland Dec 29 14:13:29.138 DEBG Failed to acquire lock, D: 3, smithay_module: XWayland Dec 29 14:13:29.138 DEBG Lock was blocked by a defunct X11 server, trying again, D: 3, smithay_module: XWayland Dec 29 14:13:29.139 DEBG Attempting to aquire an X11 display lock, D: 3, smithay_module: XWayland Dec 29 14:13:29.139 DEBG X11 lock aquired, D: 3, smithay_module: XWayland Dec 29 14:13:29.139 INFO Cleaning up X11 lock., smithay_module: XWayland Dec 29 14:13:29.139 DEBG Attempting to aquire an X11 display lock, D: 4, smithay_module: XWayland Dec 29 14:13:29.139 DEBG X11 lock aquired, D: 4, smithay_module: XWayland Dec 29 14:13:29.139 INFO Initialization completed, starting the main loop. The reason for the above behaviour is the smithay::xwayland::x11_sockets::open_x11_sockets_for_display() failed. The code successfully acquired the lock file, but then could not bind the sockets. More specifically, the concrete socket in /tmp/.X11-unix/ already existed and thus bind() failed with EADDRINUSE. (The code in X11Lock::grab() would then drop the already acquired X11Lock and its Drop impl deleted the socket. Thus, when I started things again, this time it successfully acquired display 3.) Fix this removing the socket before trying to bind it. This is also done by wlroots: In xwayland/sockets.x, the function open_socket() has the same job as smithay's open_socket() function. However, for non-abstract sockets, it would first unlink the target before trying to bind: if (addr->sun_path[0]) { unlink(addr->sun_path); } Signed-off-by: Uli Schlachter --- src/xwayland/x11_sockets.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/xwayland/x11_sockets.rs b/src/xwayland/x11_sockets.rs index 10085cc..ed33a54 100644 --- a/src/xwayland/x11_sockets.rs +++ b/src/xwayland/x11_sockets.rs @@ -108,6 +108,7 @@ impl Drop for X11Lock { /// Should only be done after the associated lockfile is aquired! fn open_x11_sockets_for_display(display: u32) -> NixResult<[UnixStream; 2]> { let path = format!("/tmp/.X11-unix/X{}", display); + let _ = ::std::fs::remove_file(&path); // We know this path is not to long, these unwrap cannot fail let fs_addr = socket::UnixAddr::new(path.as_bytes()).unwrap(); let abs_addr = socket::UnixAddr::new_abstract(path.as_bytes()).unwrap();