• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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