* F_string_too_large (with error bit) if link target path is too large for string buffer size.
* F_failure (with error bit) for any other error.
*
+ * Errors (with error bit) from: f_string_dynamic_increase_by()
+ * Errors (with error bit) from: f_string_dynamic_terminate_after()
+ *
* @see readlink()
+ *
+ * @see f_string_dynamic_increase_by()
+ * @see f_string_dynamic_terminate_after()
*/
#ifndef _di_f_file_link_read_
extern f_status_t f_file_link_read(const f_string_static_t path, const struct stat link_stat, f_string_dynamic_t * const target);
* F_string_too_large (with error bit) if link target path is too large for string buffer size.
* F_failure (with error bit) for any other error.
*
+ * Errors (with error bit) from: f_string_dynamic_increase_by()
+ * Errors (with error bit) from: f_string_dynamic_terminate_after()
+ *
* @see readlinkat()
+ *
+ * @see f_string_dynamic_increase_by()
+ * @see f_string_dynamic_terminate_after()
*/
#ifndef _di_f_file_link_read_at_
extern f_status_t f_file_link_read_at(const int at_id, const f_string_static_t path, const struct stat link_stat, f_string_dynamic_t * const target);
#if !defined(_di_f_file_link_read_) || !defined(_di_f_file_copy_)
f_status_t private_f_file_link_read(const f_string_static_t path, const struct stat link_stat, f_string_dynamic_t * const target) {
- // Create a NULL terminated string based on file stat.
- if (link_stat.st_size + 1 > target->size) {
- if (link_stat.st_size + 1 > F_array_length_t_size_d) {
- return F_status_set_error(F_string_too_large);
- }
-
- const f_status_t status = f_string_dynamic_resize(link_stat.st_size + 1, target);
- if (F_status_is_error(status)) return status;
- }
+ target->used = 0;
- memset(target->string, 0, sizeof(f_char_t) * (target->used + 1));
-
- target->used = link_stat.st_size;
+ f_status_t status = f_string_dynamic_increase_by(link_stat.st_size + 1, target);
+ if (F_status_is_error(status)) return status;
- if (readlink(path.string, target->string, target->used) < 0) {
+ if (readlink(path.string, target->string, link_stat.st_size) < 0) {
if (errno == EACCES) return F_status_set_error(F_access_denied);
if (errno == EFAULT) return F_status_set_error(F_buffer);
if (errno == EINVAL) return F_status_set_error(F_parameter);
return F_status_set_error(F_failure);
}
+ target->used = link_stat.st_size;
+
+ status = f_string_dynamic_terminate_after(target);
+ if (F_status_is_error(status)) return status;
+
return F_none;
}
#endif // !defined(_di_f_file_link_read_) || !defined(_di_f_file_copy_)
#if !defined(_di_f_file_link_read_at_) || !defined(_di_f_file_copy_at_)
f_status_t private_f_file_link_read_at(const int at_id, const f_string_static_t path, const struct stat link_stat, f_string_dynamic_t * const target) {
- // Create a NULL terminated string based on file stat.
- if (link_stat.st_size + 1 > target->size) {
- if (link_stat.st_size + 1 > F_array_length_t_size_d) {
- return F_status_set_error(F_string_too_large);
- }
-
- const f_status_t status = f_string_dynamic_resize(link_stat.st_size + 1, target);
- if (F_status_is_error(status)) return status;
- }
+ target->used = 0;
- memset(target->string, 0, sizeof(f_char_t) * (target->used + 1));
-
- target->used = link_stat.st_size;
+ f_status_t status = f_string_dynamic_increase_by(link_stat.st_size + 1, target);
+ if (F_status_is_error(status)) return status;
- if (readlinkat(at_id, path.string, target->string, target->used) < 0) {
+ if (readlinkat(at_id, path.string, target->string, link_stat.st_size) < 0) {
if (errno == EACCES) return F_status_set_error(F_access_denied);
if (errno == EBADF) return F_status_set_error(F_directory_descriptor);
if (errno == EFAULT) return F_status_set_error(F_buffer);
return F_status_set_error(F_failure);
}
+ target->used = link_stat.st_size;
+
+ status = f_string_dynamic_terminate_after(target);
+ if (F_status_is_error(status)) return status;
+
return F_none;
}
#endif // !defined(_di_f_file_link_read_at_) || !defined(_di_f_file_copy_at_)
*
* @see f_file_copy()
* @see f_file_link_read()
+ * @see f_string_dynamic_increase_by()
+ * @see f_string_dynamic_terminate_after()
*/
#if !defined(_di_f_file_link_read_) || !defined(_di_f_file_copy_)
extern f_status_t private_f_file_link_read(const f_string_static_t path, const struct stat link_stat, f_string_dynamic_t * const target) F_attribute_visibility_internal_d;
*
* @see f_file_copy_at()
* @see f_file_link_read_at()
+ * @see f_string_dynamic_increase_by()
+ * @see f_string_dynamic_terminate_after()
*/
#if !defined(_di_f_file_link_read_at_) || !defined(_di_f_file_copy_at_)
extern f_status_t private_f_file_link_read_at(const int at_id, const f_string_static_t path, const struct stat link_stat, f_string_dynamic_t * const target) F_attribute_visibility_internal_d;