1 /*
2 * Copyright (c) 2022 HPMicro
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include <errno.h>
16 #include <fcntl.h>
17 #include <stdint.h>
18 #include <stdbool.h>
19 #include <stdio.h>
20 #include <string.h>
21 #include <sys/types.h>
22 #include <sys/stat.h>
23 #include <unistd.h>
24 #include "utils_file.h"
25 #include "hal_file.h"
26
27 #define LOG_E(fmt, ...) printf(fmt, ##__VA_ARGS__)
28 #define LOG_I(fmt, ...) printf(fmt, ##__VA_ARGS__)
29
30 #define ROOT_LEN 2
31 #define MAX_PATH_LEN 40
32 #define MaxOpenFile 32
33 #define ROOT_PATH "/data"
34
35 typedef struct _File_Context {
36 int fs_fd;
37 unsigned char fd;
38 } File_Context;
39
40 static File_Context File[MaxOpenFile] = { 0 };
41
Find_Free_Num(void)42 int Find_Free_Num(void)
43 {
44 int i = MaxOpenFile;
45 for (; i > 0; i--) {
46 if (File[i - 1].fd == 0) {
47 break;
48 }
49 }
50
51 return i;
52 }
53
54
ReadModeChange(int oflag)55 int ReadModeChange(int oflag)
56 {
57 int ret = 0;
58 int buffer = 0;
59
60 buffer = (oflag & 0x000f);
61 if (buffer == O_RDONLY_FS) {
62 ret = O_RDONLY;
63 } else if (buffer == O_WRONLY_FS) {
64 ret = O_WRONLY;
65 } else if (buffer == O_RDWR_FS) {
66 ret = O_RDWR;
67 }
68
69 buffer = (oflag & 0x00f0);
70 if ((buffer & 0x0040) != 0) {
71 ret |= O_CREAT;
72 }
73
74 if ((buffer & 0x0080) != 0) {
75 ret |= O_EXCL;
76 }
77
78 buffer = (oflag & 0x0f00);
79 if ((buffer & 0x0200) != 0) {
80 ret |= O_TRUNC;
81 }
82
83 if ((buffer & 0x0400) != 0) {
84 ret |= O_APPEND;
85 }
86
87 return ret;
88 }
89
HalFileOpen(const char * path,int oflag,int mode)90 int HalFileOpen(const char *path, int oflag, int mode)
91 {
92 char *file_path;
93 int fd;
94 uint16_t path_len;
95
96 if (strlen(path) >= MAX_PATH_LEN) {
97 LOG_E("path name is too long!!!\n");
98 return -1;
99 }
100
101 fd = Find_Free_Num();
102 if (fd == 0) {
103 LOG_E("NO enougn file Space!!!\n");
104 return -1;
105 }
106
107 path_len = strlen(path) + strlen(ROOT_PATH) + ROOT_LEN;
108 file_path = (char *)malloc(path_len);
109 if (file_path == NULL) {
110 LOG_E("malloc path name buffer failed!\n");
111 return -1;
112 }
113 strcpy_s(file_path, path_len, ROOT_PATH);
114 if (strcat_s(file_path, path_len, "/") != 0) {
115 return -1;
116 }
117 if (strcat_s(file_path, path_len, path) != 0) {
118 return -1;
119 }
120
121 int fs_fd = open(file_path, ReadModeChange(oflag));
122 if (fs_fd < 0) {
123 LOG_E("open file '%s' failed, %s\r\n", file_path, strerror(errno));
124 free(file_path);
125 return -1;
126 }
127
128 File[fd - 1].fd = 1;
129 File[fd - 1].fs_fd = fs_fd;
130 free(file_path);
131
132 return fd;
133 }
134
HalFileClose(int fd)135 int HalFileClose(int fd)
136 {
137 int ret;
138
139 if ((fd > MaxOpenFile) || (fd <= 0)) {
140 return -1;
141 }
142
143 ret = close(File[fd - 1].fs_fd);
144 if (ret != 0) {
145 return -1;
146 }
147
148 File[fd - 1].fd = 0;
149 File[fd - 1].fs_fd = -1;
150
151 return ret;
152 }
153
HalFileRead(int fd,char * buf,unsigned int len)154 int HalFileRead(int fd, char *buf, unsigned int len)
155 {
156 if ((fd > MaxOpenFile) || (fd <= 0)) {
157 return -1;
158 }
159
160 return read(File[fd - 1].fs_fd, buf, len);
161 }
162
HalFileWrite(int fd,const char * buf,unsigned int len)163 int HalFileWrite(int fd, const char *buf, unsigned int len)
164 {
165 if ((fd > MaxOpenFile) || (fd <= 0)) {
166 return -1;
167 }
168
169 return write(File[fd - 1].fs_fd, buf, len);
170 }
171
HalFileDelete(const char * path)172 int HalFileDelete(const char *path)
173 {
174 char *file_path;
175 uint16_t path_len;
176
177 if (strlen(path) >= MAX_PATH_LEN) {
178 LOG_E("path name is too long!!!\n");
179 return -1;
180 }
181
182 path_len = strlen(path) + strlen(ROOT_PATH) + ROOT_LEN;
183 file_path = (char *)malloc(path_len);
184 if (file_path == NULL) {
185 LOG_E("malloc path name buffer failed!\n");
186 return -1;
187 }
188
189 strcpy_s(file_path, path_len, ROOT_PATH);
190 if (strcat_s(file_path, path_len, "/") != 0) {
191 return -1;
192 }
193 if (strcat_s(file_path, path_len, path) != 0) {
194 return -1;
195 }
196
197 int ret = unlink(file_path);
198 free(file_path);
199
200 return ret;
201 }
202
HalFileStat(const char * path,unsigned int * fileSize)203 int HalFileStat(const char *path, unsigned int *fileSize)
204 {
205 char *file_path;
206 struct stat f_info;
207 uint16_t path_len;
208
209 if (strlen(path) >= MAX_PATH_LEN) {
210 LOG_E("path name is too long!!!\n");
211 return -1;
212 }
213
214 path_len = strlen(path) + strlen(ROOT_PATH) + ROOT_LEN;
215 file_path = (char *)malloc(path_len);
216 if (file_path == NULL) {
217 LOG_E("malloc path name buffer failed!\n");
218 return -1;
219 }
220 strcpy_s(file_path, path_len, ROOT_PATH);
221 if (strcat_s(file_path, path_len, "/") != 0) {
222 return -1;
223 }
224 if (strcat_s(file_path, path_len, path) != 0) {
225 return -1;
226 }
227
228 int ret = stat(file_path, &f_info);
229 *fileSize = f_info.st_size;
230 free(file_path);
231
232 return ((ret == 0) ? 0 : -1);
233 }
234
HalFileSeek(int fd,int offset,unsigned int whence)235 int HalFileSeek(int fd, int offset, unsigned int whence)
236 {
237 int ret = 0;
238 struct stat f_info;
239
240 if ((fd > MaxOpenFile) || (fd <= 0)) {
241 return -1;
242 }
243
244 ret = fstat(File[fd - 1].fs_fd, &f_info);
245 if (ret != 0) {
246 return -1;
247 }
248
249 if (whence == SEEK_SET_FS) {
250 if (offset > f_info.st_size) {
251 ret = -1;
252 }
253 }
254
255 ret = lseek(File[fd - 1].fs_fd, offset, whence);
256 if ((ret > f_info.st_size) || (ret < 0)) {
257 return -1;
258 }
259
260 return ret;
261 }
262