ronantakizawa/codereview-bench huggingface dataset:
Repository: godotengine/godot
File: core/string/ustring.cpp (C++)

Code before:
	if (p_chars == -1) {
		p_chars = length() - p_from;
	}

	if (is_empty() || p_from < 0 || p_from >= length() || p_chars <= 0) {
		return "";
	}

	if ((p_from + p_chars) > length()) {
		p_chars = length() - p_from;
	}

	if (p_from == 0 && p_chars >= length()) {
		return String(*this);
	}

	String s;
	s.copy_from_unchecked(&get_data()[p_from], p_chars);
	return s;
}

int String::find(const String &p_str, int p_from) const {
	if (p_from < 0) {
		p_from = length() + p_from;
	}
	if (p_from < 0 || p_from >= length()) {
		return -1; // Still out of bounds
	}

	if (p_str.length() == 0 || length() == 0 || p_str.length() > length()) {
		return -1; // Won't find anything!
	}

	if (p_str.length() == 1) {
		// Optimize with single-char implementation.
		return span().find(p_str[0], p_from);
	}

	return span().find_sequence(p_str.span(), p_from);
}

int String::find(const char *p_str, int p_from) const {
	if (p_from < 0 || !p_str) {
		return -1;
	}

	const int src_len = strlen(p_str);

	const int len = length();

	if (len == 0 || src_len == 0) {

Review comment (suggestion):
Needs to account for large starting indices:

```suggestion
	if (p_from < 0 || p_from + p_str.length() > length() || p_str.is_empty()) {
```

With this, the next `if` block should be deletable entirely, if I'm not mistaken.
Same for `rfind` implementation (and `vector` versions).

Code after:
	if (p_from < 0) {
		p_from = len - str_len + p_from + 1;
	}
	if (p_from < 0 || p_from > len - str_len || str_len == 0) {
		return -1; // Still out of bounds
	}

	const char32_t *srcd = get_data();

	for (int i = p_from; i <= (len - str_len); i++) {
		bool found = true;
		for (int j = 0; j < str_len; j++) {
			int read_pos = i + j;

			if (read_pos >= len) {
				ERR_PRINT("read_pos>=length()");
				return -1;
			}

			char32_t src = _find_lower(srcd[read_pos]);
			char32_t dst = _find_lower(p_str[j]);

			if (src != dst) {
				found = false;
				break;
			}
		}

		if (found) {
			return i;
		}
	}

	return -1;
}

int String::rfind(const String &p_str, int p_from) const {
	const int str_len = p_str.length();
	const int len = length();

	if (p_from < 0) {
		p_from = len - str_len + p_from + 1;
	}
	if (p_from < 0 || p_from > len - str_len || p_str.is_empty()) {
		return -1; // Still out of bounds
	}

	if (p_str.length() == 1) {
		// Optimize with single-char implementation.
		return span().rfind(p_str[0], p_from);
	}
Repository: godotengine/godot
File: scene/gui/text_edit.cpp (C++)

Code before:
		int from_column = 0;
		if (line == p_from_line) {
			if (i == text.size()) {
				// Wrapped.

				if (p_search_flags & SEARCH_BACKWARDS) {
					from_column = text_line.length();
				} else {
					from_column = 0;
				}

			} else {
				from_column = p_from_column;
			}

		} else {
			if (p_search_flags & SEARCH_BACKWARDS) {
				from_column = text_line.length() - 1;
			} else {
				from_column = 0;
			}
		}

		pos = -1;

		int pos_from = (p_search_flags & SEARCH_BACKWARDS) ? text_line.length() - 1 : 0;
		int last_pos = -1;

		while (true) {
			if (p_search_flags & SEARCH_BACKWARDS) {
				while ((last_pos = (p_search_flags & SEARCH_MATCH_CASE) ? text_line.rfind(p_key, pos_from) : text_line.rfindn(p_key, pos_from)) != -1) {
					if (last_pos <= from_column) {
						pos = last_pos;
						break;
					}
					pos_from = last_pos - p_key.length();
					if (pos_from < 0) {
						break;
					}
				}
			} else {
				while ((last_pos = (p_search_flags & SEARCH_MATCH_CASE) ? text_line.find(p_key, pos_from) : text_line.findn(p_key, pos_from)) != -1) {
					if (last_pos >= from_column) {
						pos = last_pos;
						break;
					}
					pos_from = last_pos + p_key.length();
				}
			}

			bool is_match = true;

Review comment (suggestion):
```suggestion
		int pos_from = (p_search_flags & SEARCH_BACKWARDS) ? - 1 : 0;
```

Code after:
		}
	} else {
		p_visible_amount = Math::abs(p_visible_amount);
		for (int i = p_line_from; i >= 0; i--) {
			num_total++;
			if (!_is_line_hidden(i)) {
				num_visible++;
			}
			if (num_visible >= p_visible_amount) {
				break;
			}
		}
	}
	return num_total;
}

Point2i TextEdit::get_next_visible_line_index_offset_from(int p_line_from, int p_wrap_index_from, int p_visible_amount) const {
	// Returns the number of lines (hidden and unhidden) from (p_line_from + p_wrap_index_from) row to (p_line_from + visible_amount of unhidden and wrapped rows).
	// Wrap index is set to the wrap index of the last line.
	int wrap_index = 0;
	ERR_FAIL_INDEX_V(p_line_from, text.size(), Point2i(Math::abs(p_visible_amount), 0));

	if (!_is_hiding_enabled() && get_line_wrapping_mode() == LineWrappingMode::LINE_WRAPPING_NONE) {
		return Point2i(Math::abs(p_visible_amount), 0);
	}

	int num_visible = 0;
	int num_total = 0;
	if (p_visible_amount == 0) {
		num_total = 0;
		wrap_index = 0;
	} else if (p_visible_amount > 0) {
		int i;
		num_visible -= p_wrap_index_from;
		for (i = p_line_from; i < text.size(); i++) {
			num_total++;
			if (!_is_line_hidden(i)) {
				num_visible++;
				num_visible += get_line_wrap_count(i);
			}
			if (num_visible >= p_visible_amount) {
				break;
			}
		}
		wrap_index = get_line_wrap_count(MIN(i, text.size() - 1)) - MAX(0, num_visible - p_visible_amount);

		// If we are a hidden line, then we are the last line as we cannot reach "p_visible_amount".
		// This means we need to backtrack to get last visible line.
		// Currently, line 0 cannot be hidden so this should always be valid.
		int line = (p_line_from + num_total) - 1;
		if (_is_line_hidden(line)) {
Repository: godotengine/godot
File: core/string/ustring.cpp (C++)

Code before:

String String::substr(int p_from, int p_chars) const {
	if (p_chars == -1) {
		p_chars = length() - p_from;
	}

	if (is_empty() || p_from < 0 || p_from >= length() || p_chars <= 0) {
		return "";
	}

	if ((p_from + p_chars) > length()) {
		p_chars = length() - p_from;
	}

	if (p_from == 0 && p_chars >= length()) {
		return String(*this);
	}

	String s;
	s.copy_from_unchecked(&get_data()[p_from], p_chars);
	return s;
}

int String::find(const String &p_str, int p_from) const {
	if (p_from < 0) {
		p_from = length() + p_from;
	}
	if (p_from < 0 || p_from >= length()) {
		return -1; // Still out of bounds
	}

	if (p_str.length() == 0 || length() == 0 || p_str.length() > length()) {
		return -1; // Won't find anything!
	}

	if (p_str.length() == 1) {
		// Optimize with single-char implementation.
		return span().find(p_str[0], p_from);
	}

	return span().find_sequence(p_str.span(), p_from);
}

int String::find(const char *p_str, int p_from) const {
	if (p_from < 0 || !p_str) {
		return -1;
	}

	const int src_len = strlen(p_str);

	const int len = length();

Review comment (suggestion):
```suggestion
		p_from = length() - p_str.length() + (int64_t)p_from;
```

Code after:
	const int len = length();

	if (p_from < 0) {
		p_from = len - str_len + p_from + 1;
	}
	if (p_from < 0 || p_from > len - str_len || str_len == 0) {
		return -1; // Still out of bounds
	}

	const char32_t *srcd = get_data();

	for (int i = p_from; i <= (len - str_len); i++) {
		bool found = true;
		for (int j = 0; j < str_len; j++) {
			int read_pos = i + j;

			if (read_pos >= len) {
				ERR_PRINT("read_pos>=length()");
				return -1;
			}

			char32_t src = _find_lower(srcd[read_pos]);
			char32_t dst = _find_lower(p_str[j]);

			if (src != dst) {
				found = false;
				break;
			}
		}

		if (found) {
			return i;
		}
	}

	return -1;
}

int String::rfind(const String &p_str, int p_from) const {
	const int str_len = p_str.length();
	const int len = length();

	if (p_from < 0) {
		p_from = len - str_len + p_from + 1;
	}
	if (p_from < 0 || p_from > len - str_len || p_str.is_empty()) {
		return -1; // Still out of bounds
	}

	if (p_str.length() == 1) {
		// Optimize with single-char implementation.
Repository: godotengine/godot
File: core/string/ustring.cpp (C++)

Code before:
	}

	if ((p_from + p_chars) > length()) {
		p_chars = length() - p_from;
	}

	if (p_from == 0 && p_chars >= length()) {
		return String(*this);
	}

	String s;
	s.copy_from_unchecked(&get_data()[p_from], p_chars);
	return s;
}

int String::find(const String &p_str, int p_from) const {
	if (p_from < 0) {
		p_from = length() - p_str.length() + p_from + 1;
	}
	if (p_from < 0 || p_from > length() - p_str.length() || p_str.is_empty()) {
		return -1; // Still out of bounds
	}

	if (p_str.length() == 1) {
		// Optimize with single-char implementation.
		return span().find(p_str[0], p_from);
	}

	return span().find_sequence(p_str.span(), p_from);
}

int String::find(const char *p_str, int p_from) const {
	const int src_len = strlen(p_str);

	if (p_from < 0) {
		p_from = length() - src_len + p_from + 1;
	}
	if (p_from < 0 || p_from > length() - src_len || src_len == 0) {
		return -1; // Still out of bounds
	}

	if (src_len == 1) {
		return find_char(*p_str, p_from); // Optimize with single-char find.
	}

	const char32_t *src = get_data();

	if (src_len == 1) {
		const char32_t needle = p_str[0];

		for (int i = p_from; i < length(); i++) {

Review comment (performance):
I'm not 100% sure whether `length()` can be optimized out in `String`, since it's in RAM rather than on the stack. It may be better to just keep it in `const int len`, should also reduce your line change count again :)

Code after:
	if (p_from < 0 || p_from > len - str_len || str_len == 0) {
		return -1; // Still out of bounds
	}

	if (str_len == 1) {
		return find_char(*p_str, p_from); // Optimize with single-char find.
	}

	const char32_t *src = get_data();

	if (str_len == 1) {
		const char32_t needle = p_str[0];

		for (int i = p_from; i < len; i++) {
			if (src[i] == needle) {
				return i;
			}
		}

	} else {
		for (int i = p_from; i <= (len - str_len); i++) {
			bool found = true;
			for (int j = 0; j < str_len; j++) {
				int read_pos = i + j;

				if (read_pos >= len) {
					ERR_PRINT("read_pos>=length()");
					return -1;
				}

				if (src[read_pos] != (char32_t)p_str[j]) {
					found = false;
					break;
				}
			}

			if (found) {
				return i;
			}
		}
	}

	return -1;
}

int String::find_char(char32_t p_char, int p_from) const {
	if (p_from < 0) {
		p_from = length() + p_from;
	}
	if (p_from < 0 || p_from >= length()) {
		return -1;
Repository: godotengine/godot
File: core/string/ustring.cpp (C++)

Code before:
	}

	return -1;
}

int String::findn(const char *p_str, int p_from) const {
	const int src_len = strlen(p_str);
	const int len = length();

	if (p_from < 0) {
		p_from = len - src_len + p_from + 1;
	}
	if (p_from < 0 || p_from > len - src_len || src_len == 0) {
		return -1; // Still out of bounds
	}

	const char32_t *srcd = get_data();

	for (int i = p_from; i <= (len - src_len); i++) {
		bool found = true;
		for (int j = 0; j < src_len; j++) {
			int read_pos = i + j;

			if (read_pos >= len) {
				ERR_PRINT("read_pos>=length()");
				return -1;
			}

			char32_t src = _find_lower(srcd[read_pos]);
			char32_t dst = _find_lower(p_str[j]);

			if (src != dst) {
				found = false;
				break;
			}
		}

		if (found) {
			return i;
		}
	}

	return -1;
}

int String::rfind(const String &p_str, int p_from) const {
	const int src_len = p_str.length();
	const int len = length();

	if (p_from < 0) {
		p_from = len - src_len + p_from + 1;

Review comment (suggestion):
I don't think `src_len` is a good name for the length of the given string. You can stay agnostic, but if you want to rename them, I'd rename them all uniformly to this scheme:

```suggestion
	const int str_len = strlen(p_str);
	const int len = length();
```

Code after:

	return -1;
}

int String::rfind(const String &p_str, int p_from) const {
	const int str_len = p_str.length();
	const int len = length();

	if (p_from < 0) {
		p_from = len - str_len + p_from + 1;
	}
	if (p_from < 0 || p_from > len - str_len || p_str.is_empty()) {
		return -1; // Still out of bounds
	}

	if (p_str.length() == 1) {
		// Optimize with single-char implementation.
		return span().rfind(p_str[0], p_from);
	}

	return span().rfind_sequence(p_str.span(), p_from);
}

int String::rfind(const char *p_str, int p_from) const {
	const int str_len = strlen(p_str);
	const int len = length();

	if (p_from < 0) {
		p_from = len - str_len + p_from + 1;
	}
	if (p_from < 0 || p_from > len - str_len || str_len == 0) {
		return -1; // Still out of bounds
	}

	const char32_t *source = get_data();

	for (int i = p_from; i >= 0; i--) {
		bool found = true;
		for (int j = 0; j < str_len; j++) {
			int read_pos = i + j;

			if (read_pos >= length()) {
				ERR_PRINT("read_pos>=length()");
				return -1;
			}

			const char32_t key_needle = p_str[j];
			if (source[read_pos] != key_needle) {
				found = false;
				break;
			}
Repository: godotengine/godot
File: scene/2d/physics/collision_polygon_2d.h (C/C++)

Code before:

public:
#ifdef DEBUG_ENABLED
	virtual Rect2 _edit_get_rect() const override;
	virtual bool _edit_use_rect() const override;
	virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const override;
#endif

	void set_build_mode(BuildMode p_mode);
	BuildMode get_build_mode() const;

	void set_polygon(const Vector<Point2> &p_polygon);
	Vector<Point2> get_polygon() const;

	PackedStringArray get_configuration_warnings() const override;

	void set_disabled(bool p_disabled);
	bool is_disabled() const;

	void set_one_way_collision(bool p_enable);
	bool is_one_way_collision_enabled() const;

	void set_one_way_collision_margin(real_t p_margin);
	real_t get_one_way_collision_margin() const;

	void set_one_way_collision_direction(Vector2 p_direction);
	Vector2 get_one_way_collision_direction() const;

	CollisionPolygon2D();
};

VARIANT_ENUM_CAST(CollisionPolygon2D::BuildMode);


Review comment (suggestion):
```suggestion
	void set_one_way_collision_direction(const Vector2 &p_direction);
```

Code after:

public:
#ifdef DEBUG_ENABLED
	virtual Rect2 _edit_get_rect() const override;
	virtual bool _edit_use_rect() const override;
	virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const override;
#endif

	void set_build_mode(BuildMode p_mode);
	BuildMode get_build_mode() const;

	void set_polygon(const Vector<Point2> &p_polygon);
	Vector<Point2> get_polygon() const;

	PackedStringArray get_configuration_warnings() const override;

	void set_disabled(bool p_disabled);
	bool is_disabled() const;

	void set_one_way_collision(bool p_enable);
	bool is_one_way_collision_enabled() const;

	void set_one_way_collision_margin(real_t p_margin);
	real_t get_one_way_collision_margin() const;

	void set_one_way_collision_direction(const Vector2 &p_direction);
	Vector2 get_one_way_collision_direction() const;

	CollisionPolygon2D();
};

VARIANT_ENUM_CAST(CollisionPolygon2D::BuildMode);
Repository: godotengine/godot
File: scene/2d/physics/collision_shape_2d.h (C/C++)

Code before:
	bool _property_get_revert(const StringName &p_name, Variant &r_property) const;
	void _validate_property(PropertyInfo &p_property) const;
#endif // DEBUG_ENABLED

	static void _bind_methods();

public:
#ifdef DEBUG_ENABLED
	virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const override;
#else
	virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const;
#endif // DEBUG_ENABLED

	void set_shape(const Ref<Shape2D> &p_shape);
	Ref<Shape2D> get_shape() const;

	void set_disabled(bool p_disabled);
	bool is_disabled() const;

	void set_one_way_collision(bool p_enable);
	bool is_one_way_collision_enabled() const;

	void set_one_way_collision_margin(real_t p_margin);
	real_t get_one_way_collision_margin() const;

	void set_one_way_collision_direction(Vector2 p_one_way_collision_direction);
	Vector2 get_one_way_collision_direction() const;

	void set_debug_color(const Color &p_color);
	Color get_debug_color() const;

	PackedStringArray get_configuration_warnings() const override;

	CollisionShape2D();
};


Review comment (suggestion):
```suggestion
	void set_one_way_collision_direction(const Vector2 &p_one_way_collision_direction);
```

Code after:
	bool _property_get_revert(const StringName &p_name, Variant &r_property) const;
	void _validate_property(PropertyInfo &p_property) const;
#endif // DEBUG_ENABLED

	static void _bind_methods();

public:
#ifdef DEBUG_ENABLED
	virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const override;
#else
	virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const;
#endif // DEBUG_ENABLED

	void set_shape(const Ref<Shape2D> &p_shape);
	Ref<Shape2D> get_shape() const;

	void set_disabled(bool p_disabled);
	bool is_disabled() const;

	void set_one_way_collision(bool p_enable);
	bool is_one_way_collision_enabled() const;

	void set_one_way_collision_margin(real_t p_margin);
	real_t get_one_way_collision_margin() const;

	void set_one_way_collision_direction(const Vector2 &p_direction);
	Vector2 get_one_way_collision_direction() const;

	void set_debug_color(const Color &p_color);
	Color get_debug_color() const;

	PackedStringArray get_configuration_warnings() const override;

	CollisionShape2D();
};
Repository: godotengine/godot
File: scene/2d/physics/collision_polygon_2d.cpp (C++)

Code before:
					Vector<Vector<Vector2>> decomp = _decompose_in_convex();

					Color c(0.4, 0.9, 0.1);
					for (int i = 0; i < decomp.size(); i++) {
						c.set_hsv(Math::fmod(c.get_h() + 0.738, 1), c.get_s(), c.get_v(), 0.5);
						draw_colored_polygon(decomp[i], c);
					}
				}
#endif

				const Color stroke_color = get_tree()->get_debug_collisions_color();
				draw_polyline(polygon, stroke_color);
				// Draw the last segment.
				draw_line(polygon[polygon.size() - 1], polygon[0], stroke_color);
			}

			if (one_way_collision) {
				Color dcol = get_tree()->get_debug_collisions_color(); //0.9,0.2,0.2,0.4);
				dcol.a = 1.0;
				Vector2 line_to = 20.0 * one_way_collision_direction;
				draw_line(Vector2(), line_to, dcol, 3);
				real_t tsize = 8;

				Vector<Vector2> pts = {
					line_to + tsize * one_way_collision_direction,
					line_to + Math::SQRT12 * tsize * one_way_collision_direction.rotated(-Math::PI / 2),
					line_to + Math::SQRT12 * tsize * one_way_collision_direction.rotated(Math::PI / 2),
				};

				Vector<Color> cols{ dcol, dcol, dcol };

				draw_primitive(pts, cols, Vector<Vector2>()); //small arrow
			}
		} break;
	}
}

void CollisionPolygon2D::set_polygon(const Vector<Point2> &p_polygon) {
	polygon = p_polygon;

	{
		for (int i = 0; i < polygon.size(); i++) {
			if (i == 0) {
				aabb = Rect2(polygon[i], Size2());
			} else {
				aabb.expand_to(polygon[i]);
			}
		}
		if (aabb == Rect2()) {
			aabb = Rect2(-10, -10, 20, 20);
		} else {

Review comment (suggestion):
Not such a big deal here but we have `Vector2::orthogonal()` that you can use instead.

The same goes for CollisionShape2D.

Code after:
					Vector<Vector<Vector2>> decomp = _decompose_in_convex();

					Color c(0.4, 0.9, 0.1);
					for (int i = 0; i < decomp.size(); i++) {
						c.set_hsv(Math::fmod(c.get_h() + 0.738, 1), c.get_s(), c.get_v(), 0.5);
						draw_colored_polygon(decomp[i], c);
					}
				}
#endif

				const Color stroke_color = get_tree()->get_debug_collisions_color();
				draw_polyline(polygon, stroke_color);
				// Draw the last segment.
				draw_line(polygon[polygon.size() - 1], polygon[0], stroke_color);
			}

			if (one_way_collision) {
				Color dcol = get_tree()->get_debug_collisions_color(); //0.9,0.2,0.2,0.4);
				dcol.a = 1.0;
				Vector2 line_to = 20.0 * one_way_collision_direction;
				draw_line(Vector2(), line_to, dcol, 3);
				real_t tsize = 8;

				Vector<Vector2> pts = {
					line_to + tsize * one_way_collision_direction,
					line_to + Math::SQRT12 * tsize * one_way_collision_direction.orthogonal(),
					line_to - Math::SQRT12 * tsize * one_way_collision_direction.orthogonal(),
				};

				Vector<Color> cols{ dcol, dcol, dcol };

				draw_primitive(pts, cols, Vector<Vector2>()); //small arrow
			}
		} break;
	}
}

void CollisionPolygon2D::set_polygon(const Vector<Point2> &p_polygon) {
	polygon = p_polygon;

	{
		for (int i = 0; i < polygon.size(); i++) {
			if (i == 0) {
				aabb = Rect2(polygon[i], Size2());
			} else {
				aabb.expand_to(polygon[i]);
			}
		}
		if (aabb == Rect2()) {
			aabb = Rect2(-10, -10, 20, 20);
		} else {
Repository: godotengine/godot
File: drivers/unix/os_unix.cpp (C++)

Code before:
			// See https://stackoverflow.com/a/45472920/730797.
			continue;
		}
		return error;
	}
}

bool OS_Unix::_check_pid_is_running(const pid_t p_pid, int *r_status) const {
	const ProcessInfo *pi = process_map->getptr(p_pid);

	if (pi && !pi->is_running) {
		// Can return cached value.
		if (r_status) {
			*r_status = pi->exit_code;
		}
		return false;
	}

	int status = 0;
	const int result = _wait_for_pid_completion(p_pid, &status, WNOHANG);
	if (result == 0) {
		// Thread is still running.
		return true;
	}

	ERR_FAIL_COND_V_MSG(result == -1, false, vformat("Thread {} exited with errno: {}", p_pid, errno));
	// Thread exited normally.

	if (pi) {
		pi->is_running = false;
		pi->exit_code = status;
	}

	if (r_status) {
		*r_status = status;
	}

	return false;
}

Error OS_Unix::execute(const String &p_path, const List<String> &p_arguments, String *r_pipe, int *r_exitcode, bool read_stderr, Mutex *p_pipe_mutex, bool p_open_console) {
#ifdef __EMSCRIPTEN__
	// Don't compile this code at all to avoid undefined references.
	// Actual virtual call goes to OS_Web.
	ERR_FAIL_V(ERR_BUG);
#else
	if (r_pipe) {
		String command = "\"" + p_path + "\"";
		for (const String &arg : p_arguments) {
			command += String(" \"") + arg + "\"";
		}

Review comment (bug):
Pythonism :)
```suggestion
	ERR_FAIL_COND_V_MSG(result == -1, false, vformat("Thread %d exited with errno: %d.", (int)p_pid, errno));
```

Code after:
			// See https://stackoverflow.com/a/45472920/730797.
			continue;
		}
		return error;
	}
}

bool OS_Unix::_check_pid_is_running(const pid_t p_pid, int *r_status) const {
	const ProcessInfo *pi = process_map->getptr(p_pid);

	if (pi && !pi->is_running) {
		// Can return cached value.
		if (r_status) {
			*r_status = pi->exit_code;
		}
		return false;
	}

	int status = 0;
	const int result = _wait_for_pid_completion(p_pid, &status, WNOHANG);
	if (result == 0) {
		// Thread is still running.
		return true;
	}

	ERR_FAIL_COND_V_MSG(result == -1, false, vformat("Thread %d exited with errno: %d", (int)p_pid, errno));
	// Thread exited normally.

	status = WIFEXITED(status) ? WEXITSTATUS(status) : status;

	if (pi) {
		pi->is_running = false;
		pi->exit_code = status;
	}

	if (r_status) {
		*r_status = status;
	}

	return false;
}

Error OS_Unix::execute(const String &p_path, const List<String> &p_arguments, String *r_pipe, int *r_exitcode, bool read_stderr, Mutex *p_pipe_mutex, bool p_open_console) {
#ifdef __EMSCRIPTEN__
	// Don't compile this code at all to avoid undefined references.
	// Actual virtual call goes to OS_Web.
	ERR_FAIL_V(ERR_BUG);
#else
	if (r_pipe) {
		String command = "\"" + p_path + "\"";
		for (const String &arg : p_arguments) {