Code cleanups.
Add initializer to F_file_mode_t.
Have file closures set id to -1 even on error due to documented design of the close() function.
Provide path type for process path related file system operation failures.
Some operations do not distinguish file or directory but instead only operate on the path itself.
In these cases, the path type is now available for use.
Add F_file_found_not to standard error printer.
This allows for the standard error printer to still report the problem rather than a code.
Using the file-specific standard error printer is still the recommended approach.
/**
* File mode related functionality.
*
- * There are two types of file modes the f_file_mode_t macros associate with.
+ * There are two types of file modes that the f_file_mode_t macros are associated with.
*
* The first type is the traditional mode type, associated with mode_t.
*
#ifndef _di_f_file_mode_
typedef uint32_t f_file_mode_t;
+ #define f_file_mode_t_initialize 0
+
#define F_file_mode_t_block_special_d 0x77000000 // 0111 0111 0000 0000 0000 0000 0000 0000
#define F_file_mode_t_block_owner_d 0x00ff0000 // 0000 0000 1111 1111 0000 0000 0000 0000
#define F_file_mode_t_block_group_d 0x0000ff00 // 0000 0000 0000 0000 1111 1111 0000 0000
#define F_file_mode_t_replace_other_d 0x18 // 0001 1000
#define F_file_mode_t_replace_standard_d 0x7 // 0000 0111
- // file permission modes (mode_t).
+ // File permission modes (mode_t).
#define F_file_mode_owner_rwx_d S_IRWXU
#define F_file_mode_owner_r_d S_IRUSR
#define F_file_mode_owner_w_d S_IWUSR
#define F_file_mode_all_w_d (F_file_mode_owner_w_d | F_file_mode_group_w_d | F_file_mode_world_w_d)
#define F_file_mode_all_x_d (F_file_mode_owner_x_d | F_file_mode_group_x_d | F_file_mode_world_x_d)
- // file mode set-uid/set-gid/sticky-bits and all bits (mode_t).
+ // File mode set-uid/set-gid/sticky-bits and all bits (mode_t).
#define F_file_mode_special_set_user_d S_ISUID
#define F_file_mode_special_set_group_d S_ISGID
#define F_file_mode_special_sticky_d S_ISVTX
#define F_file_mode_special_all_d (S_ISUID | S_ISGID | S_ISVTX)
- // all permissions modes and special modes (mode_t).
+ // All permissions modes and special modes (mode_t).
#define F_file_mode_all_d (F_file_mode_special_all_d | F_file_mode_all_rwx_d)
- // special file mode combinations (mode_t).
+ // Special file mode combinations (mode_t).
#define F_file_mode_user_access_d (F_file_mode_owner_rwx_d | F_file_mode_group_rwx_d | F_file_mode_world_x_d)
#define F_file_mode_user_directory_d (F_file_mode_owner_rwx_d | F_file_mode_group_rwx_d)
#define F_file_mode_user_file_d (F_file_mode_owner_rw_d | F_file_mode_group_rw_d)
}
if (close(*id) < 0) {
+
+ // According to man pages, retrying close() after another close on error is invalid on Linux because Linux releases the descriptor before stages that cause failures.
+ if (errno != EBADF && errno != EINTR) {
+ *id = -1;
+ }
+
if (errno == EBADF) return F_status_set_error(F_file_descriptor);
if (errno == EINTR) return F_status_set_error(F_interrupt);
if (errno == EIO) return F_status_set_error(F_input_output);
}
*id = -1;
+
return F_none;
}
#endif // !defined(_di_f_file_close_) || !defined(_di_f_file_copy_) || !defined(_di_f_file_stream_close_)
#ifndef _di_fll_error_file_type_
const f_string_t fll_error_file_type_directory_s = FLL_error_file_type_directory_s;
const f_string_t fll_error_file_type_file_s = FLL_error_file_type_file_s;
+ const f_string_t fll_error_file_type_path_s = FLL_error_file_type_path_s;
const f_string_t fll_error_file_type_pipe_s = FLL_error_file_type_pipe_s;
#endif // _di_fll_error_file_type_
* fll_error_file_type_*:
* - file: File error.
* - directory: Directory error.
+ * - path: Path error.
* - pipe: Pipe error.
*/
#ifndef _di_fll_error_file_type_
enum {
fll_error_file_type_file_e = 1,
fll_error_file_type_directory_e,
+ fll_error_file_type_path_e,
fll_error_file_type_pipe_e,
};
#define FLL_error_file_type_directory_s "directory"
#define FLL_error_file_type_file_s "file"
+ #define FLL_error_file_type_path_s "path"
#define FLL_error_file_type_pipe_s "pipe"
#define FLL_error_file_type_directory_s_length 9
#define FLL_error_file_type_file_s_length 4
+ #define FLL_error_file_type_path_s_length 4
#define FLL_error_file_type_pipe_s_length 4
extern const f_string_t fll_error_file_type_directory_s;
extern const f_string_t fll_error_file_type_file_s;
+ extern const f_string_t fll_error_file_type_path_s;
extern const f_string_t fll_error_file_type_pipe_s;
#endif // _di_fll_error_file_type_
if (type == fll_error_file_type_directory_e) {
type_name = FLL_error_file_type_directory_s;
}
+ else if (type == fll_error_file_type_path_e) {
+ type_name = FLL_error_file_type_path_s;
+ }
else if (type == fll_error_file_type_pipe_e) {
type_name = FLL_error_file_type_pipe_s;
}
}
}
- if (type == fll_error_file_type_file_e || type == fll_error_file_type_directory_e) {
+ if (type == fll_error_file_type_file_e || type == fll_error_file_type_directory_e || type == fll_error_file_type_path_e) {
if (status == F_directory_found_not) {
if (print.verbosity != f_console_verbosity_quiet_e) {
flockfile(print.to.stream);
return F_false;
}
+ if (status == F_file_found_not) {
+ if (print.verbosity != f_console_verbosity_quiet_e) {
+ flockfile(print.to.stream);
+
+ fl_print_format("%c%[%SFile not found", print.to.stream, f_string_eol_s[0], print.context, print.prefix);
+
+ private_fll_error_print_function(print, function);
+
+ fl_print_format(".%]%c", print.to.stream, print.context, f_string_eol_s[0]);
+
+ funlockfile(print.to.stream);
+ }
+
+ return F_false;
+ }
+
if (status == F_memory_not) {
if (print.verbosity != f_console_verbosity_quiet_e) {
flockfile(print.to.stream);