@ -487,6 +487,123 @@ static int dbus_event(int fd, uint32_t mask, void *data) {
return 1 ;
}
static bool contains_str ( const char * needle , const char * * haystack ) {
for ( int i = 0 ; haystack [ i ] ; i + + ) {
if ( strcmp ( haystack [ i ] , needle ) = = 0 ) {
return true ;
}
}
return false ;
}
static bool get_greeter_session ( char * * session_id ) {
char * class = NULL ;
char * * user_sessions = NULL ;
int user_session_count = sd_uid_get_sessions ( getuid ( ) , 1 , & user_sessions ) ;
if ( user_session_count < 0 ) {
wlr_log ( WLR_ERROR , " Failed to get sessions " ) ;
goto out ;
}
if ( user_session_count = = 0 ) {
wlr_log ( WLR_ERROR , " User has no sessions " ) ;
goto out ;
}
for ( int i = 0 ; i < user_session_count ; + + i ) {
int ret = sd_session_get_class ( user_sessions [ i ] , & class ) ;
if ( ret < 0 ) {
continue ;
}
if ( strcmp ( class , " greeter " ) = = 0 ) {
* session_id = strdup ( user_sessions [ i ] ) ;
goto out ;
}
}
out :
free ( class ) ;
for ( int i = 0 ; i < user_session_count ; + + i ) {
free ( user_sessions [ i ] ) ;
}
free ( user_sessions ) ;
return * session_id ! = NULL ;
}
static bool get_display_session ( char * * session_id ) {
assert ( session_id ! = NULL ) ;
int ret ;
// If there's a session active for the current process then just use that
ret = sd_pid_get_session ( getpid ( ) , session_id ) ;
if ( ret = = 0 ) {
return true ;
}
char * type = NULL ;
char * state = NULL ;
// Find any active sessions for the user if the process isn't part of an
// active session itself
ret = sd_uid_get_display ( getuid ( ) , session_id ) ;
if ( ret < 0 & & ret ! = - ENODATA ) {
wlr_log ( WLR_ERROR , " Failed to get display: %s " , strerror ( - ret ) ) ;
goto error ;
}
if ( ret ! = 0 & & ! get_greeter_session ( session_id ) ) {
wlr_log ( WLR_ERROR , " Couldn't find an active session or a greeter session " ) ;
goto error ;
}
assert ( * session_id ! = NULL ) ;
// Check that the available session is graphical
ret = sd_session_get_type ( * session_id , & type ) ;
if ( ret < 0 ) {
wlr_log ( WLR_ERROR , " Couldn't get a type for session '%s': %s " ,
* session_id , strerror ( - ret ) ) ;
goto error ;
}
const char * graphical_session_types [ ] = { " wayland " , " x11 " , " mir " , NULL } ;
if ( ! contains_str ( type , graphical_session_types ) ) {
wlr_log ( WLR_ERROR , " Session '%s' isn't a graphical session (type: '%s') " ,
* session_id , type ) ;
goto error ;
}
// Check that the session is active
ret = sd_session_get_state ( * session_id , & state ) ;
if ( ret < 0 ) {
wlr_log ( WLR_ERROR , " Couldn't get state for session '%s': %s " ,
* session_id , strerror ( - ret ) ) ;
goto error ;
}
const char * active_states [ ] = { " active " , " online " , NULL } ;
if ( ! contains_str ( state , active_states ) ) {
wlr_log ( WLR_ERROR , " Session '%s' is not active " , * session_id ) ;
goto error ;
}
free ( type ) ;
free ( state ) ;
return true ;
error :
free ( type ) ;
free ( state ) ;
free ( * session_id ) ;
* session_id = NULL ;
return false ;
}
static struct wlr_session * logind_session_create ( struct wl_display * disp ) {
int ret ;
struct logind_session * session = calloc ( 1 , sizeof ( * session ) ) ;
@ -495,9 +612,7 @@ static struct wlr_session *logind_session_create(struct wl_display *disp) {
return NULL ;
}
ret = sd_pid_get_session ( getpid ( ) , & session - > id ) ;
if ( ret < 0 ) {
wlr_log ( WLR_ERROR , " Failed to get session id: %s " , strerror ( - ret ) ) ;
if ( ! get_display_session ( & session - > id ) ) {
goto error ;
}