1 /*
2 * Copyright (C) 2021-2025 Huawei Device Co., Ltd.
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
16 #include "hc_file.h"
17 #include <dirent.h>
18 #include <fcntl.h>
19 #include <sys/types.h>
20 #include <sys/stat.h>
21 #include <unistd.h>
22 #include "hc_log.h"
23 #include "hc_types.h"
24 #include "securec.h"
25 #include "string_util.h"
26
27 #ifdef __cplusplus
28 extern "C" {
29 #endif
30
31 #define MAX_FOLDER_NAME_SIZE 128
32
CreateDirectory(const char * filePath)33 static int32_t CreateDirectory(const char *filePath)
34 {
35 int32_t res;
36 char *chPtr = NULL;
37 char dirCache[MAX_FOLDER_NAME_SIZE];
38
39 chPtr = (char *)filePath;
40 while ((chPtr = strchr(chPtr, '/')) != NULL) {
41 unsigned long len = (unsigned long)((uintptr_t)chPtr - (uintptr_t)filePath);
42 if (len == 0uL) {
43 chPtr++;
44 continue;
45 }
46 if (len >= MAX_FOLDER_NAME_SIZE || memcpy_s(dirCache, sizeof(dirCache), filePath, len) != EOK) {
47 LOGE("memory copy failed");
48 return -1;
49 }
50 dirCache[len] = 0;
51 if (access(dirCache, F_OK) != 0) {
52 res = mkdir(dirCache, S_IRWXU);
53 if (res != 0) {
54 LOGE("[OS]: mkdir fail. [Res]: %" LOG_PUB "d, [errno]: %" LOG_PUB "d", res, errno);
55 return -1;
56 }
57 }
58 chPtr++;
59 }
60 return 0;
61 }
62
HcFileOpenRead(const char * path)63 static FILE *HcFileOpenRead(const char *path)
64 {
65 return fopen(path, "rb");
66 }
67
HcFileOpenWrite(const char * path)68 static FILE *HcFileOpenWrite(const char *path)
69 {
70 if (access(path, F_OK) != 0) {
71 int32_t ret = CreateDirectory(path);
72 if (ret != 0) {
73 return NULL;
74 }
75 }
76 FILE *fp = fopen(path, "wb+");
77 if (fp == NULL) {
78 LOGE("[OS]: fopen fail. [errno]: %" LOG_PUB "d", errno);
79 return NULL;
80 }
81 int res = fchmod(fileno(fp), S_IRUSR | S_IWUSR | S_IRGRP);
82 if (res != 0) {
83 LOGW("[OS]: fchmod fail. [Res]: %" LOG_PUB "d, [errno]: %" LOG_PUB "d", res, errno);
84 }
85 return fp;
86 }
87
HcFileOpen(const char * path,int mode,FileHandle * file)88 int HcFileOpen(const char *path, int mode, FileHandle *file)
89 {
90 if (path == NULL || file == NULL) {
91 return -1;
92 }
93 if (mode == MODE_FILE_READ) {
94 file->pfd = HcFileOpenRead(path);
95 } else {
96 file->pfd = HcFileOpenWrite(path);
97 }
98 if (file->pfd == NULL) {
99 return -1;
100 }
101 return 0;
102 }
103
HcFileSize(FileHandle file)104 int HcFileSize(FileHandle file)
105 {
106 FILE *fp = (FILE *)file.pfd;
107 if (fp != NULL) {
108 if (fseek(fp, 0L, SEEK_END) != 0) {
109 return -1;
110 }
111 int size = ftell(fp);
112 if (fseek(fp, 0L, SEEK_SET) != 0) {
113 return -1;
114 }
115 return size;
116 } else {
117 return -1;
118 }
119 }
120
HcFileRead(FileHandle file,void * dst,int dstSize)121 int HcFileRead(FileHandle file, void *dst, int dstSize)
122 {
123 FILE *fp = (FILE *)file.pfd;
124 if (fp == NULL || dstSize < 0 || dst == NULL) {
125 return -1;
126 }
127
128 char *dstBuffer = (char *)dst;
129 int total = 0;
130 LOGI("[OS]: file read enter. [OriSize]: %" LOG_PUB "d", dstSize);
131 while (total < dstSize) {
132 int readCount = (int)fread(dstBuffer + total, 1, dstSize - total, fp);
133 if (ferror(fp) != 0) {
134 LOGE("read file error!");
135 }
136 if (readCount == 0) {
137 return total;
138 }
139 total += readCount;
140 }
141 LOGI("[OS]: file read quit. [ReadSize]: %" LOG_PUB "d", total);
142 return total;
143 }
144
HcFileWrite(FileHandle file,const void * src,int srcSize)145 int HcFileWrite(FileHandle file, const void *src, int srcSize)
146 {
147 FILE *fp = (FILE *)file.pfd;
148 if (fp == NULL || srcSize < 0 || src == NULL) {
149 return -1;
150 }
151
152 if (fseek(fp, 0L, SEEK_SET) != 0) {
153 LOGE("[OS]: fseek file error!");
154 return -1;
155 }
156 const char *srcBuffer = (const char *)src;
157 int total = 0;
158 LOGI("[OS]: file write enter. [OriSize]: %" LOG_PUB "d", srcSize);
159 while (total < srcSize) {
160 int writeCount = (int)fwrite(srcBuffer + total, 1, srcSize - total, fp);
161 if (ferror(fp) != 0) {
162 LOGE("write file error!");
163 }
164 total += writeCount;
165 }
166 LOGI("[OS]: file write quit. [WriteSize]: %" LOG_PUB "d", total);
167 if (fflush(fp) != 0) {
168 LOGE("[OS]: fflush fail. [errno]: %" LOG_PUB "d", errno);
169 }
170 if (fsync(fileno(fp)) != 0) {
171 LOGE("[OS]: fsync fail. [errno]: %" LOG_PUB "d", errno);
172 }
173 return total;
174 }
175
HcFileClose(FileHandle file)176 void HcFileClose(FileHandle file)
177 {
178 FILE *fp = (FILE *)file.pfd;
179 if (fp == NULL) {
180 return;
181 }
182
183 (void)fclose(fp);
184 }
185
HcFileRemove(const char * path)186 void HcFileRemove(const char *path)
187 {
188 if (path == NULL) {
189 LOGE("Invalid file path");
190 return;
191 }
192 (void)remove(path);
193 }
194
HcFileGetSubFileName(const char * path,StringVector * nameVec)195 void HcFileGetSubFileName(const char *path, StringVector *nameVec)
196 {
197 DIR *dir = NULL;
198 struct dirent *entry = NULL;
199 if ((dir = opendir(path)) == NULL) {
200 LOGI("opendir failed!");
201 return;
202 }
203 while ((entry = readdir(dir)) != NULL) {
204 if (IsStrEqual(entry->d_name, ".") || IsStrEqual(entry->d_name, "..")) {
205 continue;
206 }
207 HcString subFileName = CreateString();
208 if (!StringSetPointer(&subFileName, entry->d_name)) {
209 LOGE("Failed to copy subFileName!");
210 DeleteString(&subFileName);
211 continue;
212 }
213 if (nameVec->pushBackT(nameVec, subFileName) == NULL) {
214 LOGE("Failed to push path to pathVec!");
215 DeleteString(&subFileName);
216 }
217 }
218 if (closedir(dir) < 0) {
219 LOGE("Failed to close file");
220 }
221 }
222
223 #ifdef __cplusplus
224 }
225 #endif
226