2012-04-26 09:15:22 +04:00
/*
* Helper functions for handling target threads / cpus
*
* Copyright ( C ) 2012 , LG Electronics , Namhyung Kim < namhyung . kim @ lge . com >
*
* Released under the GPL v2 .
*/
# include "target.h"
2016-07-07 17:38:09 +03:00
# include "util.h"
2012-04-26 09:15:22 +04:00
# include "debug.h"
2012-05-07 09:09:01 +04:00
# include <pwd.h>
2012-05-07 09:09:02 +04:00
# include <string.h>
2012-05-07 09:09:01 +04:00
2012-04-26 09:15:22 +04:00
2013-11-12 23:46:16 +04:00
enum target_errno target__validate ( struct target * target )
2012-04-26 09:15:22 +04:00
{
2013-11-12 23:46:16 +04:00
enum target_errno ret = TARGET_ERRNO__SUCCESS ;
2012-05-07 09:09:00 +04:00
2012-04-26 09:15:22 +04:00
if ( target - > pid )
target - > tid = target - > pid ;
/* CPU and PID are mutually exclusive */
if ( target - > tid & & target - > cpu_list ) {
target - > cpu_list = NULL ;
2013-11-12 23:46:16 +04:00
if ( ret = = TARGET_ERRNO__SUCCESS )
ret = TARGET_ERRNO__PID_OVERRIDE_CPU ;
2012-04-26 09:15:22 +04:00
}
/* UID and PID are mutually exclusive */
if ( target - > tid & & target - > uid_str ) {
target - > uid_str = NULL ;
2013-11-12 23:46:16 +04:00
if ( ret = = TARGET_ERRNO__SUCCESS )
ret = TARGET_ERRNO__PID_OVERRIDE_UID ;
2012-04-26 09:15:22 +04:00
}
/* UID and CPU are mutually exclusive */
if ( target - > uid_str & & target - > cpu_list ) {
target - > cpu_list = NULL ;
2013-11-12 23:46:16 +04:00
if ( ret = = TARGET_ERRNO__SUCCESS )
ret = TARGET_ERRNO__UID_OVERRIDE_CPU ;
2012-04-26 09:15:22 +04:00
}
2012-05-07 09:09:00 +04:00
/* PID and SYSTEM are mutually exclusive */
if ( target - > tid & & target - > system_wide ) {
2012-04-26 09:15:22 +04:00
target - > system_wide = false ;
2013-11-12 23:46:16 +04:00
if ( ret = = TARGET_ERRNO__SUCCESS )
ret = TARGET_ERRNO__PID_OVERRIDE_SYSTEM ;
2012-04-26 09:15:22 +04:00
}
2012-05-07 09:09:00 +04:00
/* UID and SYSTEM are mutually exclusive */
if ( target - > uid_str & & target - > system_wide ) {
target - > system_wide = false ;
2013-11-12 23:46:16 +04:00
if ( ret = = TARGET_ERRNO__SUCCESS )
ret = TARGET_ERRNO__UID_OVERRIDE_SYSTEM ;
2012-05-07 09:09:00 +04:00
}
2013-11-15 17:52:29 +04:00
/* THREAD and SYSTEM/CPU are mutually exclusive */
if ( target - > per_thread & & ( target - > system_wide | | target - > cpu_list ) ) {
target - > per_thread = false ;
if ( ret = = TARGET_ERRNO__SUCCESS )
ret = TARGET_ERRNO__SYSTEM_OVERRIDE_THREAD ;
}
2012-05-07 09:09:00 +04:00
return ret ;
2012-04-26 09:15:22 +04:00
}
2012-05-07 09:09:01 +04:00
2013-11-12 23:46:16 +04:00
enum target_errno target__parse_uid ( struct target * target )
2012-05-07 09:09:01 +04:00
{
struct passwd pwd , * result ;
char buf [ 1024 ] ;
const char * str = target - > uid_str ;
target - > uid = UINT_MAX ;
if ( str = = NULL )
2013-11-12 23:46:16 +04:00
return TARGET_ERRNO__SUCCESS ;
2012-05-07 09:09:01 +04:00
/* Try user name first */
getpwnam_r ( str , & pwd , buf , sizeof ( buf ) , & result ) ;
if ( result = = NULL ) {
/*
* The user name not found . Maybe it ' s a UID number .
*/
char * endptr ;
int uid = strtol ( str , & endptr , 10 ) ;
if ( * endptr ! = ' \0 ' )
2013-11-12 23:46:16 +04:00
return TARGET_ERRNO__INVALID_UID ;
2012-05-07 09:09:01 +04:00
getpwuid_r ( uid , & pwd , buf , sizeof ( buf ) , & result ) ;
if ( result = = NULL )
2013-11-12 23:46:16 +04:00
return TARGET_ERRNO__USER_NOT_FOUND ;
2012-05-07 09:09:01 +04:00
}
target - > uid = result - > pw_uid ;
2013-11-12 23:46:16 +04:00
return TARGET_ERRNO__SUCCESS ;
2012-05-07 09:09:01 +04:00
}
2012-05-07 09:09:02 +04:00
/*
2013-11-12 23:46:16 +04:00
* This must have a same ordering as the enum target_errno .
2012-05-07 09:09:02 +04:00
*/
2013-11-12 23:46:16 +04:00
static const char * target__error_str [ ] = {
2012-05-07 09:09:02 +04:00
" PID/TID switch overriding CPU " ,
" PID/TID switch overriding UID " ,
" UID switch overriding CPU " ,
" PID/TID switch overriding SYSTEM " ,
" UID switch overriding SYSTEM " ,
2013-11-15 17:52:29 +04:00
" SYSTEM/CPU switch overriding PER-THREAD " ,
2012-05-07 09:09:02 +04:00
" Invalid User: %s " ,
" Problems obtaining information for user %s " ,
} ;
2013-11-12 23:46:16 +04:00
int target__strerror ( struct target * target , int errnum ,
2012-05-07 09:09:02 +04:00
char * buf , size_t buflen )
{
int idx ;
const char * msg ;
2012-07-26 05:50:10 +04:00
BUG_ON ( buflen = = 0 ) ;
2012-07-24 01:06:54 +04:00
2012-05-07 09:09:02 +04:00
if ( errnum > = 0 ) {
2016-07-29 17:54:35 +03:00
str_error_r ( errnum , buf , buflen ) ;
2012-05-07 09:09:02 +04:00
return 0 ;
}
2013-11-12 23:46:16 +04:00
if ( errnum < __TARGET_ERRNO__START | | errnum > = __TARGET_ERRNO__END )
2012-05-07 09:09:02 +04:00
return - 1 ;
2013-11-12 23:46:16 +04:00
idx = errnum - __TARGET_ERRNO__START ;
msg = target__error_str [ idx ] ;
2012-05-07 09:09:02 +04:00
switch ( errnum ) {
2013-11-15 17:52:29 +04:00
case TARGET_ERRNO__PID_OVERRIDE_CPU . . .
TARGET_ERRNO__SYSTEM_OVERRIDE_THREAD :
2012-05-07 09:09:02 +04:00
snprintf ( buf , buflen , " %s " , msg ) ;
break ;
2013-11-12 23:46:16 +04:00
case TARGET_ERRNO__INVALID_UID :
case TARGET_ERRNO__USER_NOT_FOUND :
2012-05-07 09:09:02 +04:00
snprintf ( buf , buflen , msg , target - > uid_str ) ;
break ;
default :
/* cannot reach here */
break ;
}
return 0 ;
}