1 // SPDX-License-Identifier: GPL-2.0-only
3 * Helper functions for handling target threads/cpus
5 * Copyright (C) 2012, LG Electronics, Namhyung Kim <namhyung.kim@lge.com>
14 #include <linux/kernel.h>
15 #include <linux/string.h>
17 enum target_errno
target__validate(struct target
*target
)
19 enum target_errno ret
= TARGET_ERRNO__SUCCESS
;
22 target
->tid
= target
->pid
;
24 /* CPU and PID are mutually exclusive */
25 if (target
->tid
&& target
->cpu_list
) {
26 target
->cpu_list
= NULL
;
27 if (ret
== TARGET_ERRNO__SUCCESS
)
28 ret
= TARGET_ERRNO__PID_OVERRIDE_CPU
;
31 /* UID and PID are mutually exclusive */
32 if (target
->tid
&& target
->uid_str
) {
33 target
->uid_str
= NULL
;
34 if (ret
== TARGET_ERRNO__SUCCESS
)
35 ret
= TARGET_ERRNO__PID_OVERRIDE_UID
;
38 /* UID and CPU are mutually exclusive */
39 if (target
->uid_str
&& target
->cpu_list
) {
40 target
->cpu_list
= NULL
;
41 if (ret
== TARGET_ERRNO__SUCCESS
)
42 ret
= TARGET_ERRNO__UID_OVERRIDE_CPU
;
45 /* PID and SYSTEM are mutually exclusive */
46 if (target
->tid
&& target
->system_wide
) {
47 target
->system_wide
= false;
48 if (ret
== TARGET_ERRNO__SUCCESS
)
49 ret
= TARGET_ERRNO__PID_OVERRIDE_SYSTEM
;
52 /* UID and SYSTEM are mutually exclusive */
53 if (target
->uid_str
&& target
->system_wide
) {
54 target
->system_wide
= false;
55 if (ret
== TARGET_ERRNO__SUCCESS
)
56 ret
= TARGET_ERRNO__UID_OVERRIDE_SYSTEM
;
59 /* THREAD and SYSTEM/CPU are mutually exclusive */
60 if (target
->per_thread
&& (target
->system_wide
|| target
->cpu_list
)) {
61 target
->per_thread
= false;
62 if (ret
== TARGET_ERRNO__SUCCESS
)
63 ret
= TARGET_ERRNO__SYSTEM_OVERRIDE_THREAD
;
69 enum target_errno
target__parse_uid(struct target
*target
)
71 struct passwd pwd
, *result
;
73 const char *str
= target
->uid_str
;
75 target
->uid
= UINT_MAX
;
77 return TARGET_ERRNO__SUCCESS
;
79 /* Try user name first */
80 getpwnam_r(str
, &pwd
, buf
, sizeof(buf
), &result
);
84 * The user name not found. Maybe it's a UID number.
87 int uid
= strtol(str
, &endptr
, 10);
90 return TARGET_ERRNO__INVALID_UID
;
92 getpwuid_r(uid
, &pwd
, buf
, sizeof(buf
), &result
);
95 return TARGET_ERRNO__USER_NOT_FOUND
;
98 target
->uid
= result
->pw_uid
;
99 return TARGET_ERRNO__SUCCESS
;
103 * This must have a same ordering as the enum target_errno.
105 static const char *target__error_str
[] = {
106 "PID/TID switch overriding CPU",
107 "PID/TID switch overriding UID",
108 "UID switch overriding CPU",
109 "PID/TID switch overriding SYSTEM",
110 "UID switch overriding SYSTEM",
111 "SYSTEM/CPU switch overriding PER-THREAD",
113 "Problems obtaining information for user %s",
116 int target__strerror(struct target
*target
, int errnum
,
117 char *buf
, size_t buflen
)
125 str_error_r(errnum
, buf
, buflen
);
129 if (errnum
< __TARGET_ERRNO__START
|| errnum
>= __TARGET_ERRNO__END
)
132 idx
= errnum
- __TARGET_ERRNO__START
;
133 msg
= target__error_str
[idx
];
136 case TARGET_ERRNO__PID_OVERRIDE_CPU
...
137 TARGET_ERRNO__SYSTEM_OVERRIDE_THREAD
:
138 snprintf(buf
, buflen
, "%s", msg
);
141 case TARGET_ERRNO__INVALID_UID
:
142 case TARGET_ERRNO__USER_NOT_FOUND
:
143 snprintf(buf
, buflen
, msg
, target
->uid_str
);
147 /* cannot reach here */