Branch data Line data Source code
1 : : #include "precizer.h"
2 : : #include <errno.h>
3 : :
4 : : /**
5 : : * @brief Classify errno from a failed access() into FileAccessStatus.
6 : : *
7 : : * Maps common filesystem errors to a stable, high-level status:
8 : : * - ENOENT, ENOTDIR -> FILE_NOT_FOUND
9 : : * - EACCES, EPERM -> FILE_ACCESS_DENIED
10 : : * - otherwise -> FILE_ACCESS_ERROR
11 : : *
12 : : * @param err errno value (typically `errno` after a failed `access()` call).
13 : : * @return FileAccessStatus classification.
14 : : *
15 : : */
16 : 12376 : static FileAccessStatus classify_access_errno(int err)
17 : : {
18 [ + + - + ]: 12376 : if(err == ENOENT || err == ENOTDIR)
19 : : {
20 : 12350 : return(FILE_NOT_FOUND);
21 : : }
22 : :
23 [ - + - - ]: 26 : if(err == EACCES || err == EPERM)
24 : : {
25 : 26 : return(FILE_ACCESS_DENIED);
26 : : }
27 : :
28 : 0 : return(FILE_ACCESS_ERROR);
29 : : }
30 : :
31 : : /**
32 : : * Check access for a path, first as provided, then by its absolute form.
33 : : *
34 : : * The function preserves the errno classification from the initial `access`
35 : : * call and only overwrites it if resolving the absolute path succeeds and a
36 : : * second `access` call provides a more precise status.
37 : : *
38 : : * @param path Path to check (relative or absolute).
39 : : * @param path_size Length of the provided path.
40 : : * @param mode Access mode for `access()` (e.g., R_OK, X_OK).
41 : : * @return FILE_ACCESS_ALLOWED on success; FILE_NOT_FOUND, FILE_ACCESS_DENIED,
42 : : * or FILE_ACCESS_ERROR depending on errno classification.
43 : : */
44 : 13938 : FileAccessStatus file_check_access(
45 : : const char *path,
46 : : const size_t path_size,
47 : : const int mode)
48 : : {
49 [ + + ]: 13938 : if(access(path,mode) == 0)
50 : : {
51 : 1606 : return(FILE_ACCESS_ALLOWED);
52 : : }
53 : :
54 : 12332 : FileAccessStatus access_status = classify_access_errno(errno);
55 : :
56 : 12332 : char *absolute_path = NULL;
57 : :
58 [ + - ]: 12332 : if(TRIUMPH & path_absolute_from_relative(&absolute_path,path,path_size))
59 : : {
60 [ + + ]: 12332 : if(access(absolute_path,mode) == 0)
61 : : {
62 : 12288 : access_status = FILE_ACCESS_ALLOWED;
63 : :
64 : : } else {
65 : :
66 : 44 : access_status = classify_access_errno(errno);
67 : : }
68 : : } else {
69 : 0 : access_status = FILE_ACCESS_ERROR;
70 : : }
71 : :
72 [ + - ]: 12332 : if(absolute_path != NULL)
73 : : {
74 : 12332 : free(absolute_path);
75 : : }
76 : :
77 : 12332 : return(access_status);
78 : : }
|