diff options
| -rw-r--r-- | session/direct.c | 31 | 
1 files changed, 21 insertions, 10 deletions
diff --git a/session/direct.c b/session/direct.c index e128658a..f3be87b6 100644 --- a/session/direct.c +++ b/session/direct.c @@ -38,16 +38,26 @@ struct direct_session {  static int direct_session_open(struct wlr_session *restrict base,  		const char *restrict path) {  	struct direct_session *session = wl_container_of(base, session, base); + +	// These are the flags logind uses  	int fd = open(path, O_RDWR | O_CLOEXEC | O_NOCTTY | O_NONBLOCK);  	if (fd == -1) { -		wlr_log_errno(L_ERROR, "%s", path); +		wlr_log_errno(L_ERROR, "Cannot open %s", path);  		return -errno;  	}  	struct stat st;  	if (fstat(fd, &st) == 0 && major(st.st_rdev) == DRM_MAJOR) { +		if (drmSetMaster(fd)) { +			// Save errno, in case close() clobbers it +			int e = errno; +			wlr_log(L_ERROR, "Cannot become DRM master: %s%s", strerror(e), +				e == EINVAL ? "; is another display server running?" : ""); +			close(fd); +			return -e; +		} +  		session->drm_fd = fd; -		drmSetMaster(fd);  	}  	return fd; @@ -105,6 +115,7 @@ static int vt_handler(int signo, void *data) {  }  static bool setup_tty(struct direct_session *session, struct wl_display *display) { +	// TODO: Change this to accept any TTY, instead of just the current one  	session->tty_fd = dup(STDIN_FILENO);  	struct stat st; @@ -144,7 +155,7 @@ static bool setup_tty(struct direct_session *session, struct wl_display *display  	}  	if (ioctl(session->tty_fd, KDSETMODE, KD_GRAPHICS)) { -		wlr_log_errno(L_ERROR, "Failed to get graphics mode on tty"); +		wlr_log_errno(L_ERROR, "Failed to set graphics mode on tty");  		goto error;  	} @@ -174,23 +185,23 @@ error:  }  static struct wlr_session *direct_session_start(struct wl_display *disp) { -	struct direct_session *session = calloc(1, sizeof(*session)); -	if (!session) { -		wlr_log(L_ERROR, "Allocation failed: %s", strerror(errno)); -		return NULL; -	} -  	cap_t cap = cap_get_proc();  	cap_flag_value_t val;  	if (!cap || cap_get_flag(cap, CAP_SYS_ADMIN, CAP_PERMITTED, &val) || val != CAP_SET) {  		wlr_log(L_ERROR, "Do not have CAP_SYS_ADMIN; cannot become DRM master");  		cap_free(cap); -		goto error_session; +		return NULL;  	}  	cap_free(cap); +	struct direct_session *session = calloc(1, sizeof(*session)); +	if (!session) { +		wlr_log(L_ERROR, "Allocation failed: %s", strerror(errno)); +		return NULL; +	} +  	if (!setup_tty(session, disp)) {  		goto error_session;  	}  | 
