@ -33,7 +33,6 @@
# include <poll.h>
# include <poll.h>
# include <errno.h>
# include <errno.h>
# include <error.h>
# include <getopt.h>
# include <getopt.h>
# include <sys/types.h>
# include <sys/types.h>
@ -235,11 +234,17 @@ setup_pam(struct weston_launch *wl)
static int
static int
setup_launcher_socket ( struct weston_launch * wl )
setup_launcher_socket ( struct weston_launch * wl )
{
{
if ( socketpair ( AF_LOCAL , SOCK_SEQPACKET , 0 , wl - > sock ) < 0 )
if ( socketpair ( AF_LOCAL , SOCK_SEQPACKET , 0 , wl - > sock ) < 0 ) {
error ( 1 , errno , " socketpair failed " ) ;
fprintf ( stderr , " weston: socketpair failed: %s \n " ,
strerror ( errno ) ) ;
return - 1 ;
}
if ( fcntl ( wl - > sock [ 0 ] , F_SETFD , FD_CLOEXEC ) < 0 )
if ( fcntl ( wl - > sock [ 0 ] , F_SETFD , FD_CLOEXEC ) < 0 ) {
error ( 1 , errno , " fcntl failed " ) ;
fprintf ( stderr , " weston: fcntl failed: %s \n " ,
strerror ( errno ) ) ;
return - 1 ;
}
return 0 ;
return 0 ;
}
}
@ -474,7 +479,8 @@ handle_signal(struct weston_launch *wl)
int pid , status , ret ;
int pid , status , ret ;
if ( read ( wl - > signalfd , & sig , sizeof sig ) ! = sizeof sig ) {
if ( read ( wl - > signalfd , & sig , sizeof sig ) ! = sizeof sig ) {
error ( 0 , errno , " reading signalfd failed " ) ;
fprintf ( stderr , " weston: reading signalfd failed: %s \n " ,
strerror ( errno ) ) ;
return - 1 ;
return - 1 ;
}
}
@ -540,49 +546,83 @@ setup_tty(struct weston_launch *wl, const char *tty)
int tty0 = open ( " /dev/tty0 " , O_WRONLY | O_CLOEXEC ) ;
int tty0 = open ( " /dev/tty0 " , O_WRONLY | O_CLOEXEC ) ;
char filename [ 16 ] ;
char filename [ 16 ] ;
if ( tty0 < 0 )
if ( tty0 < 0 ) {
error ( 1 , errno , " could not open tty0 " ) ;
fprintf ( stderr , " weston: could not open tty0: %s \n " ,
strerror ( errno ) ) ;
return - 1 ;
}
if ( ioctl ( tty0 , VT_OPENQRY , & wl - > ttynr ) < 0 | | wl - > ttynr = = - 1 )
if ( ioctl ( tty0 , VT_OPENQRY , & wl - > ttynr ) < 0 | | wl - > ttynr = = - 1 )
error ( 1 , errno , " failed to find non-opened console " ) ;
{
fprintf ( stderr , " weston: failed to find non-opened console: %s \n " ,
strerror ( errno ) ) ;
return - 1 ;
}
snprintf ( filename , sizeof filename , " /dev/tty%d " , wl - > ttynr ) ;
snprintf ( filename , sizeof filename , " /dev/tty%d " , wl - > ttynr ) ;
wl - > tty = open ( filename , O_RDWR | O_NOCTTY ) ;
wl - > tty = open ( filename , O_RDWR | O_NOCTTY ) ;
close ( tty0 ) ;
close ( tty0 ) ;
}
}
if ( wl - > tty < 0 )
if ( wl - > tty < 0 ) {
error ( 1 , errno , " failed to open tty " ) ;
fprintf ( stderr , " weston: failed to open tty: %s \n " ,
strerror ( errno ) ) ;
return - 1 ;
}
if ( fstat ( wl - > tty , & buf ) = = - 1 | |
if ( fstat ( wl - > tty , & buf ) = = - 1 | |
major ( buf . st_rdev ) ! = TTY_MAJOR | | minor ( buf . st_rdev ) = = 0 )
major ( buf . st_rdev ) ! = TTY_MAJOR | | minor ( buf . st_rdev ) = = 0 ) {
error ( 1 , 0 , " weston-launch must be run from a virtual terminal " ) ;
fprintf ( stderr , " weston: weston-launch must be run from a virtual terminal \n " ) ;
return - 1 ;
}
if ( tty ) {
if ( tty ) {
if ( fstat ( wl - > tty , & buf ) < 0 )
if ( fstat ( wl - > tty , & buf ) < 0 ) {
error ( 1 , errno , " stat %s failed " , tty ) ;
fprintf ( stderr , " weston: stat %s failed: %s \n " , tty ,
strerror ( errno ) ) ;
return - 1 ;
}
if ( major ( buf . st_rdev ) ! = TTY_MAJOR )
if ( major ( buf . st_rdev ) ! = TTY_MAJOR ) {
error ( 1 , 0 , " invalid tty device: %s " , tty ) ;
fprintf ( stderr ,
" weston: invalid tty device: %s \n " , tty ) ;
return - 1 ;
}
wl - > ttynr = minor ( buf . st_rdev ) ;
wl - > ttynr = minor ( buf . st_rdev ) ;
}
}
if ( ioctl ( wl - > tty , KDGKBMODE , & wl - > kb_mode ) )
if ( ioctl ( wl - > tty , KDGKBMODE , & wl - > kb_mode ) ) {
error ( 1 , errno , " failed to get current keyboard mode: %m \n " ) ;
fprintf ( stderr ,
" weston: failed to get current keyboard mode: %s " ,
strerror ( errno ) ) ;
return - 1 ;
}
if ( ioctl ( wl - > tty , KDSKBMUTE , 1 ) & &
if ( ioctl ( wl - > tty , KDSKBMUTE , 1 ) & &
ioctl ( wl - > tty , KDSKBMODE , K_OFF ) )
ioctl ( wl - > tty , KDSKBMODE , K_OFF ) ) {
error ( 1 , errno , " failed to set K_OFF keyboard mode: %m \n " ) ;
fprintf ( stderr ,
" weston: failed to set K_OFF keyboard mode: %s \n " ,
strerror ( errno ) ) ;
return - 1 ;
}
if ( ioctl ( wl - > tty , KDSETMODE , KD_GRAPHICS ) )
if ( ioctl ( wl - > tty , KDSETMODE , KD_GRAPHICS ) ) {
error ( 1 , errno , " failed to set KD_GRAPHICS mode on tty: %m \n " ) ;
fprintf ( stderr ,
" weston: failed to set KD_GRAPHICS mode on tty: %s \n " ,
strerror ( errno ) ) ;
return - 1 ;
}
mode . mode = VT_PROCESS ;
mode . mode = VT_PROCESS ;
mode . relsig = SIGUSR1 ;
mode . relsig = SIGUSR1 ;
mode . acqsig = SIGUSR2 ;
mode . acqsig = SIGUSR2 ;
if ( ioctl ( wl - > tty , VT_SETMODE , & mode ) < 0 )
if ( ioctl ( wl - > tty , VT_SETMODE , & mode ) < 0 ) {
error ( 1 , errno , " failed to take control of vt handling \n " ) ;
fprintf ( stderr ,
" weston: failed to take control of vt handling %s \n " ,
strerror ( errno ) ) ;
return - 1 ;
}
return 0 ;
return 0 ;
}
}
@ -595,10 +635,16 @@ setup_session(struct weston_launch *wl, char **child_argv)
int i ;
int i ;
if ( wl - > tty ! = STDIN_FILENO ) {
if ( wl - > tty ! = STDIN_FILENO ) {
if ( setsid ( ) < 0 )
if ( setsid ( ) < 0 ) {
error ( 1 , errno , " setsid failed " ) ;
fprintf ( stderr , " weston: setsid failed %s \n " ,
if ( ioctl ( wl - > tty , TIOCSCTTY , 0 ) < 0 )
strerror ( errno ) ) ;
error ( 1 , errno , " TIOCSCTTY failed - tty is in use " ) ;
exit ( EXIT_FAILURE ) ;
}
if ( ioctl ( wl - > tty , TIOCSCTTY , 0 ) < 0 ) {
fprintf ( stderr , " TIOCSCTTY failed - tty is in use %s \n " ,
strerror ( errno ) ) ;
exit ( EXIT_FAILURE ) ;
}
}
}
term = getenv ( " TERM " ) ;
term = getenv ( " TERM " ) ;
@ -614,7 +660,7 @@ setup_session(struct weston_launch *wl, char **child_argv)
if ( env ) {
if ( env ) {
for ( i = 0 ; env [ i ] ; + + i ) {
for ( i = 0 ; env [ i ] ; + + i ) {
if ( putenv ( env [ i ] ) ! = 0 )
if ( putenv ( env [ i ] ) ! = 0 )
error ( 0 , 0 , " putenv %s failed " , env [ i ] ) ;
fprintf ( stderr , " putenv %s failed \n " , env [ i ] ) ;
}
}
free ( env ) ;
free ( env ) ;
}
}
@ -638,8 +684,11 @@ drop_privileges(struct weston_launch *wl)
# ifdef HAVE_INITGROUPS
# ifdef HAVE_INITGROUPS
initgroups ( wl - > pw - > pw_name , wl - > pw - > pw_gid ) < 0 | |
initgroups ( wl - > pw - > pw_name , wl - > pw - > pw_gid ) < 0 | |
# endif
# endif
setuid ( wl - > pw - > pw_uid ) < 0 )
setuid ( wl - > pw - > pw_uid ) < 0 ) {
error ( 1 , errno , " dropping privileges failed " ) ;
fprintf ( stderr , " weston: dropping privileges failed %s \n " ,
strerror ( errno ) ) ;
exit ( EXIT_FAILURE ) ;
}
}
}
static void
static void
@ -678,7 +727,8 @@ launch_compositor(struct weston_launch *wl, int argc, char *argv[])
execv ( child_argv [ 0 ] , child_argv ) ;
execv ( child_argv [ 0 ] , child_argv ) ;
error ( 1 , errno , " exec failed " ) ;
fprintf ( stderr , " weston: exec failed: %s \n " , strerror ( errno ) ) ;
exit ( EXIT_FAILURE ) ;
}
}
static void
static void
@ -713,8 +763,10 @@ main(int argc, char *argv[])
switch ( c ) {
switch ( c ) {
case ' u ' :
case ' u ' :
wl . new_user = optarg ;
wl . new_user = optarg ;
if ( getuid ( ) ! = 0 )
if ( getuid ( ) ! = 0 ) {
error ( 1 , 0 , " Permission denied. -u allowed for root only " ) ;
fprintf ( stderr , " weston: Permission denied. -u allowed for root only \n " ) ;
exit ( EXIT_FAILURE ) ;
}
break ;
break ;
case ' t ' :
case ' t ' :
tty = optarg ;
tty = optarg ;
@ -730,27 +782,38 @@ main(int argc, char *argv[])
}
}
}
}
if ( ( argc - optind ) > ( MAX_ARGV_SIZE - 6 ) )
if ( ( argc - optind ) > ( MAX_ARGV_SIZE - 6 ) ) {
error ( 1 , E2BIG , " Too many arguments to pass to weston " ) ;
fprintf ( stderr ,
" weston: Too many arguments to pass to weston: %s \n " ,
strerror ( E2BIG ) ) ;
exit ( EXIT_FAILURE ) ;
}
if ( tty & & ! wl . new_user )
if ( tty & & ! wl . new_user ) {
error ( 1 , 0 , " -t/--tty option requires -u/--user option as well " ) ;
fprintf ( stderr , " weston: -t/--tty option requires -u/--user option as well \n " ) ;
exit ( EXIT_FAILURE ) ;
}
if ( wl . new_user )
if ( wl . new_user )
wl . pw = getpwnam ( wl . new_user ) ;
wl . pw = getpwnam ( wl . new_user ) ;
else
else
wl . pw = getpwuid ( getuid ( ) ) ;
wl . pw = getpwuid ( getuid ( ) ) ;
if ( wl . pw = = NULL )
if ( wl . pw = = NULL ) {
error ( 1 , errno , " failed to get username " ) ;
fprintf ( stderr , " weston: failed to get username: %s \n " ,
strerror ( errno ) ) ;
exit ( EXIT_FAILURE ) ;
}
if ( ! weston_launch_allowed ( & wl ) )
if ( ! weston_launch_allowed ( & wl ) ) {
error ( 1 , 0 , " Permission denied. You should either: \n "
fprintf ( stderr , " Permission denied. You should either: \n "
# ifdef HAVE_SYSTEMD_LOGIN
# ifdef HAVE_SYSTEMD_LOGIN
" - run from an active and local (systemd) session. \n "
" - run from an active and local (systemd) session. \n "
# else
# else
" - enable systemd session support for weston-launch. \n "
" - enable systemd session support for weston-launch. \n "
# endif
# endif
" - or add yourself to the 'weston-launch' group. " ) ;
" - or add yourself to the 'weston-launch' group. \n " ) ;
exit ( EXIT_FAILURE ) ;
}
if ( setup_tty ( & wl , tty ) < 0 )
if ( setup_tty ( & wl , tty ) < 0 )
exit ( EXIT_FAILURE ) ;
exit ( EXIT_FAILURE ) ;
@ -765,8 +828,10 @@ main(int argc, char *argv[])
exit ( EXIT_FAILURE ) ;
exit ( EXIT_FAILURE ) ;
wl . child = fork ( ) ;
wl . child = fork ( ) ;
if ( wl . child = = - 1 )
if ( wl . child = = - 1 ) {
error ( EXIT_FAILURE , errno , " fork failed " ) ;
fprintf ( stderr , " weston: fork failed %s \n " , strerror ( errno ) ) ;
exit ( EXIT_FAILURE ) ;
}
if ( wl . child = = 0 )
if ( wl . child = = 0 )
launch_compositor ( & wl , argc - optind , argv + optind ) ;
launch_compositor ( & wl , argc - optind , argv + optind ) ;