1060ff233Sopenharmony_ci/*
2060ff233Sopenharmony_ci * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3060ff233Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4060ff233Sopenharmony_ci * you may not use this file except in compliance with the License.
5060ff233Sopenharmony_ci * You may obtain a copy of the License at
6060ff233Sopenharmony_ci *
7060ff233Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8060ff233Sopenharmony_ci *
9060ff233Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10060ff233Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11060ff233Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12060ff233Sopenharmony_ci * See the License for the specific language governing permissions and
13060ff233Sopenharmony_ci * limitations under the License.
14060ff233Sopenharmony_ci */
15060ff233Sopenharmony_ci
16060ff233Sopenharmony_ci#include "softbus_adapter_file.h"
17060ff233Sopenharmony_ci
18060ff233Sopenharmony_ci#include <errno.h>
19060ff233Sopenharmony_ci#include <fcntl.h>
20060ff233Sopenharmony_ci#include <securec.h>
21060ff233Sopenharmony_ci#include <sys/stat.h>
22060ff233Sopenharmony_ci#include <sys/types.h>
23060ff233Sopenharmony_ci#include <unistd.h>
24060ff233Sopenharmony_ci
25060ff233Sopenharmony_ci#include "comm_log.h"
26060ff233Sopenharmony_ci#include "softbus_adapter_errcode.h"
27060ff233Sopenharmony_ci#include "softbus_errcode.h"
28060ff233Sopenharmony_ci
29060ff233Sopenharmony_cistatic int32_t SoftBusCreateFile(const char *fileName)
30060ff233Sopenharmony_ci{
31060ff233Sopenharmony_ci    if (fileName == NULL) {
32060ff233Sopenharmony_ci        return SOFTBUS_FILE_ERR;
33060ff233Sopenharmony_ci    }
34060ff233Sopenharmony_ci    char dirPath[SOFTBUS_MAX_PATH_LEN] = {0};
35060ff233Sopenharmony_ci
36060ff233Sopenharmony_ci    char *dir = (char *)fileName;
37060ff233Sopenharmony_ci    while ((dir = strchr(dir, SOFTBUS_PATH_SEPRATOR)) != NULL) {
38060ff233Sopenharmony_ci        uint32_t len = (uint32_t)(dir - fileName);
39060ff233Sopenharmony_ci        if (len == 0) { // skip root
40060ff233Sopenharmony_ci            dir++;
41060ff233Sopenharmony_ci            continue;
42060ff233Sopenharmony_ci        }
43060ff233Sopenharmony_ci        if (memcpy_s(dirPath, sizeof(dirPath), fileName, len) != EOK) {
44060ff233Sopenharmony_ci            COMM_LOGE(COMM_ADAPTER, "memory copy dir name failed");
45060ff233Sopenharmony_ci            return SOFTBUS_ERR;
46060ff233Sopenharmony_ci        }
47060ff233Sopenharmony_ci        dirPath[len] = 0;
48060ff233Sopenharmony_ci        if (access(dirPath, F_OK) != 0) {
49060ff233Sopenharmony_ci            int32_t ret = mkdir(dirPath, S_IRWXU);
50060ff233Sopenharmony_ci            if (ret != 0) {
51060ff233Sopenharmony_ci                COMM_LOGE(COMM_ADAPTER, "make dir failed, ret=%{public}d", ret);
52060ff233Sopenharmony_ci                return SOFTBUS_ERR;
53060ff233Sopenharmony_ci            }
54060ff233Sopenharmony_ci        }
55060ff233Sopenharmony_ci        dir++;
56060ff233Sopenharmony_ci    }
57060ff233Sopenharmony_ci    int32_t fd = open(fileName, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
58060ff233Sopenharmony_ci    if (fd < 0) {
59060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "create file failed, errno=%{public}d", errno);
60060ff233Sopenharmony_ci        return SOFTBUS_ERR;
61060ff233Sopenharmony_ci    }
62060ff233Sopenharmony_ci    close(fd);
63060ff233Sopenharmony_ci    return SOFTBUS_OK;
64060ff233Sopenharmony_ci}
65060ff233Sopenharmony_ci
66060ff233Sopenharmony_ciint32_t SoftBusReadFile(int32_t fd, void *readBuf, uint32_t maxLen)
67060ff233Sopenharmony_ci{
68060ff233Sopenharmony_ci    if (readBuf == NULL) {
69060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "softbus read file [buff is null]");
70060ff233Sopenharmony_ci        return SOFTBUS_INVALID_PARAM;
71060ff233Sopenharmony_ci    }
72060ff233Sopenharmony_ci    int64_t len = read(fd, readBuf, maxLen);
73060ff233Sopenharmony_ci    if (len < 0) {
74060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "softbus read file fail. errno=%{public}s", strerror(errno));
75060ff233Sopenharmony_ci    }
76060ff233Sopenharmony_ci    return len;
77060ff233Sopenharmony_ci}
78060ff233Sopenharmony_ci
79060ff233Sopenharmony_cistatic int32_t ReadFullFile(const char *fileName, char *readBuf, uint32_t maxLen, int32_t *size)
80060ff233Sopenharmony_ci{
81060ff233Sopenharmony_ci    if (fileName == NULL || readBuf == NULL || maxLen == 0 || size == NULL) {
82060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "ReadFile fail param is invalid");
83060ff233Sopenharmony_ci        return SOFTBUS_FILE_ERR;
84060ff233Sopenharmony_ci    }
85060ff233Sopenharmony_ci
86060ff233Sopenharmony_ci    int32_t fd = open(fileName, O_RDONLY, S_IRUSR | S_IWUSR);
87060ff233Sopenharmony_ci    if (fd < 0) {
88060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "ReadFile open file fail, errno=%{public}s", strerror(errno));
89060ff233Sopenharmony_ci        return SOFTBUS_FILE_ERR;
90060ff233Sopenharmony_ci    }
91060ff233Sopenharmony_ci    int32_t fileLen = lseek(fd, 0, SEEK_END);
92060ff233Sopenharmony_ci    if (fileLen <= 0) {
93060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "ReadFile len error, fileLen=%{public}d, errno=%{public}s", fileLen, strerror(errno));
94060ff233Sopenharmony_ci        close(fd);
95060ff233Sopenharmony_ci        return SOFTBUS_FILE_ERR;
96060ff233Sopenharmony_ci    }
97060ff233Sopenharmony_ci    if (fileLen > (int32_t)maxLen) {
98060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "ReadFile over max len, fileLen=%{public}d, maxLen=%{public}u", fileLen, maxLen);
99060ff233Sopenharmony_ci        close(fd);
100060ff233Sopenharmony_ci        return SOFTBUS_FILE_ERR;
101060ff233Sopenharmony_ci    }
102060ff233Sopenharmony_ci    int32_t ret = lseek(fd, 0, SEEK_SET);
103060ff233Sopenharmony_ci    if (ret < 0) {
104060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "ReadFile lseek file fail, ret=%{public}d, errno=%{public}s", ret, strerror(errno));
105060ff233Sopenharmony_ci        close(fd);
106060ff233Sopenharmony_ci        return SOFTBUS_FILE_ERR;
107060ff233Sopenharmony_ci    }
108060ff233Sopenharmony_ci    ret = read(fd, readBuf, fileLen);
109060ff233Sopenharmony_ci    if (ret < 0) {
110060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "ReadFile read fail, ret=%{public}d, errno=%{public}s", ret, strerror(errno));
111060ff233Sopenharmony_ci        close(fd);
112060ff233Sopenharmony_ci        return SOFTBUS_FILE_ERR;
113060ff233Sopenharmony_ci    }
114060ff233Sopenharmony_ci    close(fd);
115060ff233Sopenharmony_ci    *size = fileLen;
116060ff233Sopenharmony_ci    return SOFTBUS_OK;
117060ff233Sopenharmony_ci}
118060ff233Sopenharmony_ci
119060ff233Sopenharmony_ciint32_t SoftBusReadFullFileAndSize(const char *fileName, char *readBuf, uint32_t maxLen, int32_t *size)
120060ff233Sopenharmony_ci{
121060ff233Sopenharmony_ci    return ReadFullFile(fileName, readBuf, maxLen, size);
122060ff233Sopenharmony_ci}
123060ff233Sopenharmony_ci
124060ff233Sopenharmony_ciint32_t SoftBusReadFullFile(const char *fileName, char *readBuf, uint32_t maxLen)
125060ff233Sopenharmony_ci{
126060ff233Sopenharmony_ci    int32_t size = 0;
127060ff233Sopenharmony_ci    return ReadFullFile(fileName, readBuf, maxLen, &size);
128060ff233Sopenharmony_ci}
129060ff233Sopenharmony_ci
130060ff233Sopenharmony_ciint32_t SoftBusWriteFile(const char *fileName, const char *writeBuf, uint32_t len)
131060ff233Sopenharmony_ci{
132060ff233Sopenharmony_ci    if (fileName == NULL || writeBuf == NULL || len == 0) {
133060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "softbus write file para is invalid");
134060ff233Sopenharmony_ci        return SOFTBUS_FILE_ERR;
135060ff233Sopenharmony_ci    }
136060ff233Sopenharmony_ci    if (access(fileName, F_OK) != 0 && SoftBusCreateFile(fileName) != SOFTBUS_OK) {
137060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "create file fail");
138060ff233Sopenharmony_ci        return SOFTBUS_FILE_ERR;
139060ff233Sopenharmony_ci    }
140060ff233Sopenharmony_ci    int32_t fd = open(fileName, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
141060ff233Sopenharmony_ci    if (fd < 0) {
142060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "WriteFile open file fail errno=%{public}s", strerror(errno));
143060ff233Sopenharmony_ci        return SOFTBUS_FILE_ERR;
144060ff233Sopenharmony_ci    }
145060ff233Sopenharmony_ci    int32_t ret = write(fd, writeBuf, len);
146060ff233Sopenharmony_ci    if (len > INT32_MAX || ret != (int32_t)len) {
147060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "WriteFile write fail, len=%{public}u, ret=%{public}d, errno=%{public}s",
148060ff233Sopenharmony_ci            len, ret, strerror(errno));
149060ff233Sopenharmony_ci        close(fd);
150060ff233Sopenharmony_ci        return SOFTBUS_FILE_ERR;
151060ff233Sopenharmony_ci    }
152060ff233Sopenharmony_ci    fsync(fd);
153060ff233Sopenharmony_ci    close(fd);
154060ff233Sopenharmony_ci    return SOFTBUS_OK;
155060ff233Sopenharmony_ci}
156060ff233Sopenharmony_ci
157060ff233Sopenharmony_ciint32_t SoftBusWriteFileFd(int32_t fd, const char *writeBuf, uint32_t len)
158060ff233Sopenharmony_ci{
159060ff233Sopenharmony_ci    if (writeBuf == NULL || len == 0) {
160060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "softbus write file fd para is invalid");
161060ff233Sopenharmony_ci        return SOFTBUS_FILE_ERR;
162060ff233Sopenharmony_ci    }
163060ff233Sopenharmony_ci    int32_t ret = write(fd, writeBuf, len);
164060ff233Sopenharmony_ci    if (ret != (int32_t)len) {
165060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "WriteFileFd write fail, len=%{public}u, ret=%{public}d, errno=%{public}s",
166060ff233Sopenharmony_ci            len, ret, strerror(errno));
167060ff233Sopenharmony_ci    }
168060ff233Sopenharmony_ci    return ret;
169060ff233Sopenharmony_ci}
170060ff233Sopenharmony_ci
171060ff233Sopenharmony_ciint32_t SoftBusOpenFile(const char *fileName, int32_t flags)
172060ff233Sopenharmony_ci{
173060ff233Sopenharmony_ci    if (fileName == NULL) {
174060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "softbus open file [fileName is null]");
175060ff233Sopenharmony_ci        return SOFTBUS_INVALID_FD;
176060ff233Sopenharmony_ci    }
177060ff233Sopenharmony_ci    int32_t fd = open(fileName, flags);
178060ff233Sopenharmony_ci    if (fd < 0) {
179060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "softbus open file [open fail], errno=%{public}s", strerror(errno));
180060ff233Sopenharmony_ci        return SOFTBUS_INVALID_FD;
181060ff233Sopenharmony_ci    }
182060ff233Sopenharmony_ci    return fd;
183060ff233Sopenharmony_ci}
184060ff233Sopenharmony_ci
185060ff233Sopenharmony_ciint32_t SoftBusOpenFileWithPerms(const char *fileName, int32_t flags, int32_t perms)
186060ff233Sopenharmony_ci{
187060ff233Sopenharmony_ci    if (fileName == NULL) {
188060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "softbus open with perms file [fileName is null]");
189060ff233Sopenharmony_ci        return SOFTBUS_INVALID_FD;
190060ff233Sopenharmony_ci    }
191060ff233Sopenharmony_ci    int32_t fd = open(fileName, flags, perms);
192060ff233Sopenharmony_ci    if (fd < 0) {
193060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "softbus open with perms file [open fail], errno=%{public}s", strerror(errno));
194060ff233Sopenharmony_ci        return SOFTBUS_INVALID_FD;
195060ff233Sopenharmony_ci    }
196060ff233Sopenharmony_ci    return fd;
197060ff233Sopenharmony_ci}
198060ff233Sopenharmony_ci
199060ff233Sopenharmony_civoid SoftBusRemoveFile(const char *fileName)
200060ff233Sopenharmony_ci{
201060ff233Sopenharmony_ci    if (fileName == NULL) {
202060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "softbus remove file [fileName is null]");
203060ff233Sopenharmony_ci        return;
204060ff233Sopenharmony_ci    }
205060ff233Sopenharmony_ci    if (remove(fileName) != 0) {
206060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "softbus remove file fail. errno=%{public}s", strerror(errno));
207060ff233Sopenharmony_ci        return;
208060ff233Sopenharmony_ci    }
209060ff233Sopenharmony_ci}
210060ff233Sopenharmony_ci
211060ff233Sopenharmony_civoid SoftBusCloseFile(int32_t fd)
212060ff233Sopenharmony_ci{
213060ff233Sopenharmony_ci    if (fd <= SOFTBUS_INVALID_FD) {
214060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "softbus close file [fd is invalid]");
215060ff233Sopenharmony_ci        return;
216060ff233Sopenharmony_ci    }
217060ff233Sopenharmony_ci    if (close(fd) != 0) {
218060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "softbus close file fail. errno=%{public}s", strerror(errno));
219060ff233Sopenharmony_ci        return;
220060ff233Sopenharmony_ci    }
221060ff233Sopenharmony_ci}
222060ff233Sopenharmony_ci
223060ff233Sopenharmony_ciint64_t SoftBusPreadFile(int32_t fd, void *buf, uint64_t readBytes, uint64_t offset)
224060ff233Sopenharmony_ci{
225060ff233Sopenharmony_ci    if (buf == NULL) {
226060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "softbus pread file [buff is null]");
227060ff233Sopenharmony_ci        return SOFTBUS_ERR;
228060ff233Sopenharmony_ci    }
229060ff233Sopenharmony_ci    int64_t len = pread(fd, buf, readBytes, offset);
230060ff233Sopenharmony_ci    if (len < 0) {
231060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "softbus pread file fail. errno=%{public}s", strerror(errno));
232060ff233Sopenharmony_ci    }
233060ff233Sopenharmony_ci    return len;
234060ff233Sopenharmony_ci}
235060ff233Sopenharmony_ci
236060ff233Sopenharmony_ciint64_t SoftBusPwriteFile(int32_t fd, const void *buf, uint64_t writeBytes, uint64_t offset)
237060ff233Sopenharmony_ci{
238060ff233Sopenharmony_ci    if (buf == NULL) {
239060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "softbus pwrite file [buff is null]");
240060ff233Sopenharmony_ci        return SOFTBUS_ERR;
241060ff233Sopenharmony_ci    }
242060ff233Sopenharmony_ci    int64_t len = pwrite(fd, buf, writeBytes, offset);
243060ff233Sopenharmony_ci    if (len < 0) {
244060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "softbus pwrite file fail. errno=%{public}s", strerror(errno));
245060ff233Sopenharmony_ci    }
246060ff233Sopenharmony_ci    return len;
247060ff233Sopenharmony_ci}
248060ff233Sopenharmony_ci
249060ff233Sopenharmony_ciint32_t SoftBusAccessFile(const char *pathName, int32_t mode)
250060ff233Sopenharmony_ci{
251060ff233Sopenharmony_ci    if (pathName == NULL) {
252060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "softbus access path [pathName is null]");
253060ff233Sopenharmony_ci        return SOFTBUS_ERR;
254060ff233Sopenharmony_ci    }
255060ff233Sopenharmony_ci
256060ff233Sopenharmony_ci    int32_t ret = access(pathName, mode);
257060ff233Sopenharmony_ci    if (ret != 0) {
258060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "softbus access path fail, ret=%{public}d, errno=%{public}s", ret, strerror(errno));
259060ff233Sopenharmony_ci        return SOFTBUS_ERR;
260060ff233Sopenharmony_ci    }
261060ff233Sopenharmony_ci    return SOFTBUS_OK;
262060ff233Sopenharmony_ci}
263060ff233Sopenharmony_ci
264060ff233Sopenharmony_ciint32_t SoftBusMakeDir(const char *pathName, int32_t mode)
265060ff233Sopenharmony_ci{
266060ff233Sopenharmony_ci    if (pathName == NULL) {
267060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "softbus mkdir file [pathName is null]");
268060ff233Sopenharmony_ci        return SOFTBUS_ERR;
269060ff233Sopenharmony_ci    }
270060ff233Sopenharmony_ci
271060ff233Sopenharmony_ci    int32_t ret = mkdir(pathName, mode);
272060ff233Sopenharmony_ci    if (ret == 0) {
273060ff233Sopenharmony_ci        return SOFTBUS_ADAPTER_OK;
274060ff233Sopenharmony_ci    } else if ((ret == -1) && (errno == EEXIST)) {
275060ff233Sopenharmony_ci        return SOFTBUS_ADAPTER_FILE_EXIST;
276060ff233Sopenharmony_ci    } else {
277060ff233Sopenharmony_ci        return SOFTBUS_ADAPTER_ERR;
278060ff233Sopenharmony_ci    }
279060ff233Sopenharmony_ci}
280060ff233Sopenharmony_ciint32_t SoftBusGetFileSize(const char *fileName, uint64_t *fileSize)
281060ff233Sopenharmony_ci{
282060ff233Sopenharmony_ci    if ((fileName == NULL) || (fileSize == NULL)) {
283060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "softbus mkdir file [fileName or fileSize is null]");
284060ff233Sopenharmony_ci        return SOFTBUS_ERR;
285060ff233Sopenharmony_ci    }
286060ff233Sopenharmony_ci
287060ff233Sopenharmony_ci    struct stat statBuff;
288060ff233Sopenharmony_ci    if (stat(fileName, &statBuff) < 0) {
289060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "stat file fail");
290060ff233Sopenharmony_ci        return SOFTBUS_ERR;
291060ff233Sopenharmony_ci    } else {
292060ff233Sopenharmony_ci        *fileSize = statBuff.st_size;
293060ff233Sopenharmony_ci    }
294060ff233Sopenharmony_ci
295060ff233Sopenharmony_ci    return SOFTBUS_OK;
296060ff233Sopenharmony_ci}
297060ff233Sopenharmony_ci
298060ff233Sopenharmony_cichar *SoftBusRealPath(const char *path, char *absPath)
299060ff233Sopenharmony_ci{
300060ff233Sopenharmony_ci    if ((path == NULL) || (absPath == NULL)) {
301060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "softbus realpath [path or absPath is null]");
302060ff233Sopenharmony_ci        return NULL;
303060ff233Sopenharmony_ci    }
304060ff233Sopenharmony_ci
305060ff233Sopenharmony_ci    char *realPath = NULL;
306060ff233Sopenharmony_ci    if (realpath(path, absPath) == NULL) {
307060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "realpath failed, errno=%{public}s", strerror(errno));
308060ff233Sopenharmony_ci        return NULL;
309060ff233Sopenharmony_ci    } else {
310060ff233Sopenharmony_ci        realPath = absPath;
311060ff233Sopenharmony_ci    }
312060ff233Sopenharmony_ci    return realPath;
313060ff233Sopenharmony_ci}
314