+
+kern_return_t
+thread_set_state_from_user(
+ thread_t thread,
+ int flavor,
+ thread_state_t state,
+ mach_msg_type_number_t state_count)
+{
+ return thread_set_state_internal(thread, flavor, state, state_count, TRUE);
+}
+
+kern_return_t
+thread_convert_thread_state(
+ thread_t thread,
+ int direction,
+ thread_state_flavor_t flavor,
+ thread_state_t in_state, /* pointer to IN array */
+ mach_msg_type_number_t in_state_count,
+ thread_state_t out_state, /* pointer to OUT array */
+ mach_msg_type_number_t *out_state_count) /*IN/OUT*/
+{
+ kern_return_t kr;
+ thread_t to_thread = THREAD_NULL;
+ thread_t from_thread = THREAD_NULL;
+ mach_msg_type_number_t state_count = in_state_count;
+
+ if (direction != THREAD_CONVERT_THREAD_STATE_TO_SELF &&
+ direction != THREAD_CONVERT_THREAD_STATE_FROM_SELF) {
+ return KERN_INVALID_ARGUMENT;
+ }
+
+ if (thread == THREAD_NULL) {
+ return KERN_INVALID_ARGUMENT;
+ }
+
+ if (state_count > *out_state_count) {
+ return KERN_INSUFFICIENT_BUFFER_SIZE;
+ }
+
+ if (direction == THREAD_CONVERT_THREAD_STATE_FROM_SELF) {
+ to_thread = thread;
+ from_thread = current_thread();
+ } else {
+ to_thread = current_thread();
+ from_thread = thread;
+ }
+
+ /* Authenticate and convert thread state to kernel representation */
+ kr = machine_thread_state_convert_from_user(from_thread, flavor,
+ in_state, state_count);
+
+ /* Return early if one of the thread was jop disabled while other wasn't */
+ if (kr != KERN_SUCCESS) {
+ return kr;
+ }
+
+ /* Convert thread state to target thread user representation */
+ kr = machine_thread_state_convert_to_user(to_thread, flavor,
+ in_state, &state_count);
+
+ if (kr == KERN_SUCCESS) {
+ if (state_count <= *out_state_count) {
+ memcpy(out_state, in_state, state_count * sizeof(uint32_t));
+ *out_state_count = state_count;
+ } else {
+ kr = KERN_INSUFFICIENT_BUFFER_SIZE;
+ }
+ }
+
+ return kr;
+}
+