1- //@ignore-target: windows # No pthreads on Windows
1+ //@ignore-target: windows # No pthreads or prctl on Windows
22use std:: ffi:: { CStr , CString } ;
33use std:: thread;
44
55const MAX_THREAD_NAME_LEN : usize = {
66 cfg_if:: cfg_if! {
7- if #[ cfg( any( target_os = "linux" ) ) ] {
7+ if #[ cfg( any( target_os = "linux" , target_os = "android" ) ) ] {
88 16
99 } else if #[ cfg( any( target_os = "illumos" , target_os = "solaris" ) ) ] {
1010 32
@@ -36,6 +36,10 @@ fn main() {
3636 0
3737 } else if #[ cfg( target_os = "macos" ) ] {
3838 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>( ) ) }
3943 } else {
4044 compile_error!( "set_thread_name not supported for this OS" )
4145 }
@@ -59,6 +63,10 @@ fn main() {
5963 libc:: pthread_get_name_np( libc:: pthread_self( ) , name. as_mut_ptr( ) . cast( ) , name. len( ) )
6064 } ;
6165 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>( ) ) }
6270 } else {
6371 compile_error!( "get_thread_name not supported for this OS" )
6472 }
@@ -98,30 +106,32 @@ fn main() {
98106 }
99107
100108 // Test what happens when the buffer is too short even for the short name.
101- let res = get_thread_name ( & mut buf[ ..4 ] ) ;
102109 cfg_if:: cfg_if! {
103110 if #[ cfg( any( target_os = "freebsd" , target_os = "macos" ) ) ] {
104111 // On macOS and FreeBSD it's not an error for the buffer to be
105112 // too short for the thread name -- they truncate instead.
113+ let res = get_thread_name( & mut buf[ ..4 ] ) ;
106114 assert_eq!( res, 0 ) ;
107115 let cstr = CStr :: from_bytes_until_nul( & buf) . unwrap( ) ;
108116 assert_eq!( cstr. to_bytes_with_nul( ) . len( ) , 4 ) ;
109117 assert!( short_name. as_bytes( ) . starts_with( cstr. to_bytes( ) ) ) ;
110- } else {
118+ } else if # [ cfg ( not ( target_os = "android" ) ) ] {
111119 // The rest should give an error.
120+ let res = get_thread_name( & mut buf[ ..4 ] ) ;
112121 assert_eq!( res, libc:: ERANGE ) ;
113122 }
114123 }
115124
116125 // Test zero-sized buffer.
117- let res = get_thread_name ( & mut [ ] ) ;
118126 cfg_if:: cfg_if! {
119127 if #[ cfg( any( target_os = "freebsd" , target_os = "macos" ) ) ] {
120128 // On macOS and FreeBSD it's not an error for the buffer to be
121129 // too short for the thread name -- even with size 0.
130+ let res = get_thread_name( & mut [ ] ) ;
122131 assert_eq!( res, 0 ) ;
123- } else {
132+ } else if # [ cfg ( not ( target_os = "android" ) ) ] {
124133 // The rest should give an error.
134+ let res = get_thread_name( & mut [ ] ) ;
125135 assert_eq!( res, libc:: ERANGE ) ;
126136 }
127137 }
@@ -140,10 +150,15 @@ fn main() {
140150 // Names of all size are supported.
141151 assert!( cstr. to_bytes_with_nul( ) . len( ) <= MAX_THREAD_NAME_LEN ) ;
142152 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 .
145155 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 ) ] ) ;
147162 } else {
148163 // Name is too long.
149164 assert!( cstr. to_bytes_with_nul( ) . len( ) > MAX_THREAD_NAME_LEN ) ;
@@ -164,16 +179,17 @@ fn main() {
164179 assert_eq ! ( cstr. to_bytes( ) , truncated_name. as_bytes( ) ) ;
165180
166181 // Test what happens when our buffer is just one byte too small.
167- let res = get_thread_name ( & mut buf[ ..truncated_name. len ( ) ] ) ;
168182 cfg_if:: cfg_if! {
169183 if #[ cfg( any( target_os = "freebsd" , target_os = "macos" ) ) ] {
170184 // On macOS and FreeBSD it's not an error for the buffer to be
171185 // too short for the thread name -- they truncate instead.
186+ let res = get_thread_name( & mut buf[ ..truncated_name. len( ) ] ) ;
172187 assert_eq!( res, 0 ) ;
173188 let cstr = CStr :: from_bytes_until_nul( & buf) . unwrap( ) ;
174189 assert_eq!( cstr. to_bytes( ) , & truncated_name. as_bytes( ) [ ..( truncated_name. len( ) - 1 ) ] ) ;
175- } else {
190+ } else if # [ cfg ( not ( target_os = "android" ) ) ] {
176191 // The rest should give an error.
192+ let res = get_thread_name( & mut buf[ ..truncated_name. len( ) ] ) ;
177193 assert_eq!( res, libc:: ERANGE ) ;
178194 }
179195 }
0 commit comments