1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
|
/*
* Copyright (c) 2006-2025 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "syscall_internal.h"
/**
* @brief Retrieves information about a file or directory.
*
* This system call obtains metadata about the specified file or directory and stores it in
* the `buf` structure. The metadata includes attributes such as file size, permissions,
* ownership, and timestamps.
*
* @param[in] file A pointer to the path of the file or directory to be queried.
* The path should be a null-terminated string.
* @param[out] buf A pointer to a `struct stat` structure where the file's metadata
* will be stored. This structure must be allocated by the caller.
*
* @return sysret_t Returns a status code:
* - `0`: The operation completed successfully, and the metadata
* has been written to `buf`.
* - Other error codes may indicate issues with the file path.
*
* @note The `file` path must be valid and accessible by the calling process. Ensure that
* the `buf` pointer points to a properly allocated memory region.
*
* @warning Passing a `NULL` pointer for `file` or `buf` may result in undefined behavior.
* Check all inputs before invoking this function to avoid potential issues.
*/
sysret_t sys_stat(const char *file, struct stat *buf)
{
int ret = 0;
size_t len;
size_t copy_len;
char *copy_path;
struct stat statbuff = { 0 };
if (!lwp_user_accessable((void *)buf, sizeof(struct stat)))
{
return -EFAULT;
}
len = lwp_user_strlen(file);
if (len <= 0)
{
return -EFAULT;
}
copy_path = (char *)rt_malloc(len + 1);
if (!copy_path)
{
return -ENOMEM;
}
copy_len = lwp_get_from_user(copy_path, (void *)file, len);
if (copy_len == 0)
{
rt_free(copy_path);
return -EFAULT;
}
copy_path[copy_len] = '\0';
ret = _SYS_WRAP(stat(copy_path, &statbuff));
rt_free(copy_path);
if (ret == 0)
{
lwp_put_to_user(buf, &statbuff, sizeof statbuff);
}
return ret;
}
/**
* @brief Retrieves metadata about a file or symbolic link.
*
* This system call obtains metadata for the specified file or symbolic link and stores
* it in the `buf` structure. Unlike `sys_stat`, if the specified path refers to a
* symbolic link, this function retrieves information about the link itself, not the
* target it points to.
*
* @param[in] file A pointer to the path of the file or symbolic link to be queried.
* The path must be a null-terminated string.
* @param[out] buf A pointer to a `struct stat` structure where the metadata will be
* stored. This structure must be allocated by the caller.
*
* @return sysret_t Returns a status code:
* - `0`: The operation completed successfully, and the metadata
* has been written to `buf`.
* - Other error codes may indicate issues with the file path.
*
* @note This function is particularly useful for handling symbolic links when you want
* to get information about the link itself rather than the target file or directory.
* The `file` path must be valid and accessible by the calling process.
*
* @warning Passing a `NULL` pointer for `file` or `buf` may result in undefined behavior.
* Always check inputs for validity before invoking this function.
*/
sysret_t sys_lstat(const char *file, struct stat *buf)
{
int ret = 0;
size_t len;
size_t copy_len;
char *copy_path;
struct stat statbuff = { 0 };
if (!lwp_user_accessable((void *)buf, sizeof(struct stat)))
{
return -EFAULT;
}
len = lwp_user_strlen(file);
if (len <= 0)
{
return -EFAULT;
}
copy_path = (char *)rt_malloc(len + 1);
if (!copy_path)
{
return -ENOMEM;
}
copy_len = lwp_get_from_user(copy_path, (void *)file, len);
if (copy_len == 0)
{
rt_free(copy_path);
return -EFAULT;
}
copy_path[copy_len] = '\0';
#ifdef RT_USING_DFS_V2
ret = _SYS_WRAP(dfs_file_lstat(copy_path, &statbuff));
#else
ret = _SYS_WRAP(stat(copy_path, &statbuff));
#endif
rt_free(copy_path);
if (ret == 0)
{
lwp_put_to_user(buf, &statbuff, sizeof statbuff);
}
return ret;
}
|