client: Allow absolute paths in WAYLAND_DISPLAY

In order to support system compositor instances, it is necessary to
allow clients' wl_display_connect() to find the compositor's listening
socket somewhere outside of XDG_RUNTIME_DIR. For a full account, see
the discussion beginning here:

https://lists.freedesktop.org/archives/wayland-devel/2017-November/035664.html

This change adjusts the client-side connection logic so that, if
WAYLAND_DISPLAY is formatted as an absolute pathname, the socket
connection attempt is made to just $WAYLAND_DISPLAY rather than
usual user-private location $XDG_RUNTIME_DIR/$WAYLAND_DISPLAY.

This change is based on Davide Bettio's submission of the same concept
at:

https://lists.freedesktop.org/archives/wayland-devel/2015-August/023838.html.

v4 changes:

* Improved internal comments and some boundary-condition
  error checks in test case.
* Refer to compositor as "Wayland server" rather than "Wayland
  display" in wl_display_connect() doxygen comments.
* Remove redundant descriptions of parameter-interpretation
  mechanics from wl_display_connect() manpage. Reworked things
  to make it clear that 'name' and $WAYLAND_DISLAY are each
  capable of encoding absolute server socket paths.
* Remove callout to reference implementation behavior in protocol
  documented. In its place there is now a simple statement that
  implementations can optionally support absolute socket paths.

v3 changes:

* Added test case.
* Clarified documentation to note that 'name' parameter to wl_display_connect()
  can also be an absolute path.

v2 changes:

* Added backward incompatibility note to wl_display_connect() manpage.
* Rephased wl_display_connect() manpage changes to precisely match actual
  changed behavior.
* Added mention of new absolute path behavior in wl_display_connect()
  doxygen comments.
* Mentioned new absolute path interpretation of WAYLAND_DISPLAY in
  protocol documentation.

Signed-off-by: Matt Hoosier <matt.hoosier@gmail.com>
Acked-by: Jonas Ådahl <jadahl@gmail.com>
Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
This commit is contained in:
Matt Hoosier 2017-11-27 08:54:54 -06:00 committed by Pekka Paalanen
parent de24f4dd76
commit 1b6521e695
4 changed files with 177 additions and 16 deletions

View file

@ -857,9 +857,17 @@ connect_to_socket(const char *name)
socklen_t size;
const char *runtime_dir;
int name_size, fd;
bool path_is_absolute;
if (name == NULL)
name = getenv("WAYLAND_DISPLAY");
if (name == NULL)
name = "wayland-0";
path_is_absolute = name[0] == '/';
runtime_dir = getenv("XDG_RUNTIME_DIR");
if (!runtime_dir) {
if (!runtime_dir && !path_is_absolute) {
wl_log("error: XDG_RUNTIME_DIR not set in the environment.\n");
/* to prevent programs reporting
* "failed to create display: Success" */
@ -867,25 +875,32 @@ connect_to_socket(const char *name)
return -1;
}
if (name == NULL)
name = getenv("WAYLAND_DISPLAY");
if (name == NULL)
name = "wayland-0";
fd = wl_os_socket_cloexec(PF_LOCAL, SOCK_STREAM, 0);
if (fd < 0)
return -1;
memset(&addr, 0, sizeof addr);
addr.sun_family = AF_LOCAL;
name_size =
snprintf(addr.sun_path, sizeof addr.sun_path,
"%s/%s", runtime_dir, name) + 1;
if (!path_is_absolute) {
name_size =
snprintf(addr.sun_path, sizeof addr.sun_path,
"%s/%s", runtime_dir, name) + 1;
} else {
/* absolute path */
name_size =
snprintf(addr.sun_path, sizeof addr.sun_path,
"%s", name) + 1;
}
assert(name_size > 0);
if (name_size > (int)sizeof addr.sun_path) {
wl_log("error: socket path \"%s/%s\" plus null terminator"
" exceeds 108 bytes\n", runtime_dir, name);
if (!path_is_absolute) {
wl_log("error: socket path \"%s/%s\" plus null terminator"
" exceeds %i bytes\n", runtime_dir, name, (int) sizeof(addr.sun_path));
} else {
wl_log("error: socket path \"%s\" plus null terminator"
" exceeds %i bytes\n", name, (int) sizeof(addr.sun_path));
}
close(fd);
/* to prevent programs reporting
* "failed to add socket: Success" */
@ -994,6 +1009,16 @@ wl_display_connect_to_fd(int fd)
* its value will be replaced with the WAYLAND_DISPLAY environment
* variable if it is set, otherwise display "wayland-0" will be used.
*
* If \c name is an absolute path, then that path is used as-is for
* the location of the socket at which the Wayland server is listening;
* no qualification inside XDG_RUNTIME_DIR is attempted.
*
* If \c name is \c NULL and the WAYLAND_DISPLAY environment variable
* is set to an absolute pathname, then that pathname is used as-is
* for the socket in the same manner as if \c name held an absolute
* path. Support for absolute paths in \c name and WAYLAND_DISPLAY
* is present since Wayland version 1.15.
*
* \memberof wl_display
*/
WL_EXPORT struct wl_display *