1
- //@ignore-target: windows # No pthreads on Windows
1
+ //@ignore-target: windows # No pthreads or prctl on Windows
2
2
use std:: ffi:: { CStr , CString } ;
3
3
use std:: thread;
4
4
5
5
const MAX_THREAD_NAME_LEN : usize = {
6
6
cfg_if:: cfg_if! {
7
- if #[ cfg( any( target_os = "linux" ) ) ] {
7
+ if #[ cfg( any( target_os = "linux" , target_os = "android" ) ) ] {
8
8
16
9
9
} else if #[ cfg( any( target_os = "illumos" , target_os = "solaris" ) ) ] {
10
10
32
@@ -36,6 +36,10 @@ fn main() {
36
36
0
37
37
} else if #[ cfg( target_os = "macos" ) ] {
38
38
unsafe { libc:: pthread_setname_np( name. as_ptr( ) . cast( ) ) }
39
+ } else if #[ cfg( target_os = "android" ) ] {
40
+ // FIXME: Use PR_SET_NAME constant when https://github.com/rust-lang/libc/pull/3941 lands.
41
+ const PR_SET_NAME : i32 = 15 ;
42
+ unsafe { libc:: prctl( PR_SET_NAME , name. as_ptr( ) . cast:: <libc:: c_char>( ) ) }
39
43
} else {
40
44
compile_error!( "set_thread_name not supported for this OS" )
41
45
}
@@ -59,6 +63,10 @@ fn main() {
59
63
libc:: pthread_get_name_np( libc:: pthread_self( ) , name. as_mut_ptr( ) . cast( ) , name. len( ) )
60
64
} ;
61
65
0
66
+ } else if #[ cfg( target_os = "android" ) ] {
67
+ // FIXME: Use PR_GET_NAME constant when https://github.com/rust-lang/libc/pull/3941 lands.
68
+ const PR_GET_NAME : i32 = 16 ;
69
+ unsafe { libc:: prctl( PR_GET_NAME , name. as_mut_ptr( ) . cast:: <libc:: c_char>( ) ) }
62
70
} else {
63
71
compile_error!( "get_thread_name not supported for this OS" )
64
72
}
@@ -98,30 +106,32 @@ fn main() {
98
106
}
99
107
100
108
// Test what happens when the buffer is too short even for the short name.
101
- let res = get_thread_name ( & mut buf[ ..4 ] ) ;
102
109
cfg_if:: cfg_if! {
103
110
if #[ cfg( any( target_os = "freebsd" , target_os = "macos" ) ) ] {
104
111
// On macOS and FreeBSD it's not an error for the buffer to be
105
112
// too short for the thread name -- they truncate instead.
113
+ let res = get_thread_name( & mut buf[ ..4 ] ) ;
106
114
assert_eq!( res, 0 ) ;
107
115
let cstr = CStr :: from_bytes_until_nul( & buf) . unwrap( ) ;
108
116
assert_eq!( cstr. to_bytes_with_nul( ) . len( ) , 4 ) ;
109
117
assert!( short_name. as_bytes( ) . starts_with( cstr. to_bytes( ) ) ) ;
110
- } else {
118
+ } else if # [ cfg ( not ( target_os = "android" ) ) ] {
111
119
// The rest should give an error.
120
+ let res = get_thread_name( & mut buf[ ..4 ] ) ;
112
121
assert_eq!( res, libc:: ERANGE ) ;
113
122
}
114
123
}
115
124
116
125
// Test zero-sized buffer.
117
- let res = get_thread_name ( & mut [ ] ) ;
118
126
cfg_if:: cfg_if! {
119
127
if #[ cfg( any( target_os = "freebsd" , target_os = "macos" ) ) ] {
120
128
// On macOS and FreeBSD it's not an error for the buffer to be
121
129
// too short for the thread name -- even with size 0.
130
+ let res = get_thread_name( & mut [ ] ) ;
122
131
assert_eq!( res, 0 ) ;
123
- } else {
132
+ } else if # [ cfg ( not ( target_os = "android" ) ) ] {
124
133
// The rest should give an error.
134
+ let res = get_thread_name( & mut [ ] ) ;
125
135
assert_eq!( res, libc:: ERANGE ) ;
126
136
}
127
137
}
@@ -140,10 +150,15 @@ fn main() {
140
150
// Names of all size are supported.
141
151
assert!( cstr. to_bytes_with_nul( ) . len( ) <= MAX_THREAD_NAME_LEN ) ;
142
152
assert_eq!( res, 0 ) ;
143
- } else if #[ cfg( target_os = "macos " ) ] {
144
- // Name is too long .
153
+ } else if #[ cfg( target_os = "android " ) ] {
154
+ // Names are truncated by the Linux kernel .
145
155
assert!( cstr. to_bytes_with_nul( ) . len( ) > MAX_THREAD_NAME_LEN ) ;
146
- assert_eq!( res, libc:: ENAMETOOLONG ) ;
156
+ assert_eq!( res, 0 ) ;
157
+
158
+ let mut buf = vec![ 0u8 ; MAX_THREAD_NAME_LEN ] ;
159
+ assert_eq!( get_thread_name( & mut buf) , 0 ) ;
160
+ let cstr = CStr :: from_bytes_until_nul( & buf) . unwrap( ) ;
161
+ assert_eq!( cstr. to_bytes( ) , & long_name. as_bytes( ) [ ..( MAX_THREAD_NAME_LEN - 1 ) ] ) ;
147
162
} else {
148
163
// Name is too long.
149
164
assert!( cstr. to_bytes_with_nul( ) . len( ) > MAX_THREAD_NAME_LEN ) ;
@@ -164,16 +179,17 @@ fn main() {
164
179
assert_eq ! ( cstr. to_bytes( ) , truncated_name. as_bytes( ) ) ;
165
180
166
181
// Test what happens when our buffer is just one byte too small.
167
- let res = get_thread_name ( & mut buf[ ..truncated_name. len ( ) ] ) ;
168
182
cfg_if:: cfg_if! {
169
183
if #[ cfg( any( target_os = "freebsd" , target_os = "macos" ) ) ] {
170
184
// On macOS and FreeBSD it's not an error for the buffer to be
171
185
// too short for the thread name -- they truncate instead.
186
+ let res = get_thread_name( & mut buf[ ..truncated_name. len( ) ] ) ;
172
187
assert_eq!( res, 0 ) ;
173
188
let cstr = CStr :: from_bytes_until_nul( & buf) . unwrap( ) ;
174
189
assert_eq!( cstr. to_bytes( ) , & truncated_name. as_bytes( ) [ ..( truncated_name. len( ) - 1 ) ] ) ;
175
- } else {
190
+ } else if # [ cfg ( not ( target_os = "android" ) ) ] {
176
191
// The rest should give an error.
192
+ let res = get_thread_name( & mut buf[ ..truncated_name. len( ) ] ) ;
177
193
assert_eq!( res, libc:: ERANGE ) ;
178
194
}
179
195
}
0 commit comments