• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 "platform_specific.h"
17 
18 #include <ctime>
19 #include <cstdlib>
20 #include <cstring>
21 #include <climits>
22 
23 #include <dirent.h>
24 #include <fcntl.h>
25 #include <sys/stat.h>
26 #include <sys/time.h>
27 #include <sys/types.h>
28 #include <unistd.h>
29 #if defined OS_TYPE_WINDOWS
30 #include <io.h>
31 #include <stdlib.h>
32 #include <windows.h>
33 #endif
34 
35 #include "db_errno.h"
36 #include "log_print.h"
37 #include "securec.h"
38 
39 namespace DistributedDB {
40 namespace OS {
41 /*
42  * Common part that is the same between each os
43  */
44 #if defined OS_TYPE_WINDOWS
45 namespace {
46     const int ACCESS_MODE_EXISTENCE = 0;
47 }
48 
49 struct FileHandle {
50     int handle = -1;
51 };
52 
CheckPathExistence(const std::string & filePath)53 bool CheckPathExistence(const std::string &filePath)
54 {
55     int ret = _access(filePath.c_str(), ACCESS_MODE_EXISTENCE);
56     LOGI("CheckPathExistence %s error:%d", filePath.c_str(), ret);
57     return (ret == 0);
58 }
59 
RenameFilePath(const std::string & oldFilePath,const std::string & newFilePath)60 int RenameFilePath(const std::string &oldFilePath, const std::string &newFilePath)
61 {
62     int errCode = rename(oldFilePath.c_str(), newFilePath.c_str());
63     if (errCode < 0) {
64         LOGE("[Rename] Rename file fail. err = %d", errno);
65         return -E_SYSTEM_API_FAIL;
66     }
67     LOGI("Rename file path successfully!");
68     return E_OK;
69 }
70 
RemoveFile(const std::string & filePath)71 int RemoveFile(const std::string &filePath)
72 {
73     int errCode = remove(filePath.c_str());
74     if (errCode < 0) {
75         LOGE("[RemoveFile] Remove file fail %s %d err = %d", filePath.c_str(), errCode, errno);
76         return -E_SYSTEM_API_FAIL;
77     }
78     LOGI("Remove file successfully!");
79     return E_OK;
80 }
81 
CalFileSize(const std::string & fileUrl,uint64_t & size)82 int CalFileSize(const std::string &fileUrl, uint64_t &size)
83 {
84     struct _stat64 fileStat;
85     if (fileUrl.empty() || _stat64(fileUrl.c_str(), &fileStat) < 0 || fileStat.st_size < 0) {
86         int errCode = (errno == ENOENT) ? -E_NOT_FOUND : -E_INVALID_DB;
87         LOGD("Get file[%zu] size failed, errno [%d].", fileUrl.size(), errno);
88         return errCode;
89     }
90 
91     size = static_cast<uint64_t>(fileStat.st_size);
92     return E_OK;
93 }
94 
SplitFilePath(const std::string & filePath,std::string & fileDir,std::string & fileName)95 void SplitFilePath(const std::string &filePath, std::string &fileDir, std::string &fileName)
96 {
97     if (filePath.empty()) {
98         return;
99     }
100 
101     auto slashPos = filePath.find_last_of('/');
102     if (slashPos == std::string::npos) {
103         fileName = filePath;
104         fileDir = "";
105         return;
106     }
107 
108     fileDir = filePath.substr(0, slashPos);
109     fileName = filePath.substr(slashPos + 1);
110     return;
111 }
112 
MakeDBDirectory(const std::string & directory)113 int MakeDBDirectory(const std::string &directory)
114 {
115     int errCode = mkdir(directory.c_str());
116     if (errCode < 0) {
117         LOGE("[MakeDir] Make directory fail:%d.", errno);
118         return -E_SYSTEM_API_FAIL;
119     }
120     return E_OK;
121 }
122 
RemoveDBDirectory(const std::string & directory)123 int RemoveDBDirectory(const std::string &directory)
124 {
125     int ret = rmdir(directory.c_str());
126     LOGI("CheckPathExistence %s ret:%d error %d", directory.c_str(), ret, errno);
127     return ret;
128 }
129 
CreateFileByFileName(const std::string & fileName)130 int CreateFileByFileName(const std::string &fileName)
131 {
132     int fp = _open(fileName.c_str(), (O_WRONLY | O_CREAT), _S_IREAD | _S_IWRITE);
133     if (fp < 0) {
134         LOGE("[CreateFile] Create file fail:%d.", errno);
135         return -E_SYSTEM_API_FAIL;
136     }
137     close(fp);
138     return E_OK;
139 }
140 
GetRealPath(const std::string & inOriPath,std::string & outRealPath)141 int GetRealPath(const std::string &inOriPath, std::string &outRealPath)
142 {
143     const unsigned int MAX_PATH_LENGTH = PATH_MAX;
144     if (inOriPath.length() > MAX_PATH_LENGTH || MAX_PATH_LENGTH > 0x10000) { // max limit is 64K(0x10000).
145         LOGE("[RealPath] OriPath too long.");
146         return -E_INVALID_ARGS;
147     }
148 
149     char *realPath = new (std::nothrow) char[MAX_PATH_LENGTH + 1];
150     if (realPath == nullptr) {
151         return -E_OUT_OF_MEMORY;
152     }
153     if (memset_s(realPath, MAX_PATH_LENGTH + 1, 0, MAX_PATH_LENGTH + 1) != EOK) {
154         delete [] realPath;
155         return -E_SECUREC_ERROR;
156     }
157 
158     if (_fullpath(realPath, inOriPath.c_str(), MAX_PATH_LENGTH) == nullptr) {
159         LOGE("[OS] Realpath error:%d.", errno);
160         delete [] realPath;
161         return -E_SYSTEM_API_FAIL;
162     }
163     outRealPath = std::string(realPath);
164     delete [] realPath;
165     return E_OK;
166 }
167 namespace {
168     const uint64_t MULTIPLES_BETWEEN_MICROSECONDS_AND_NANOSECONDS = 1000;
169     const uint64_t MULTIPLES_BETWEEN_MICROSECONDS_AND_100_NANOSECONDS = 10;
170     const uint64_t MICROSECONDS_OFFSET = 11644473600000000;  // microseconds from January 1, 1601 to January 1, 1970
171     const uint64_t UINT32_BIT_LENGTH = 32;
172 }
173 
GetCurrentSysTimeInMicrosecond(uint64_t & outTime)174 int GetCurrentSysTimeInMicrosecond(uint64_t &outTime)
175 {
176     FILETIME rawTime;
177     GetSystemTimeAsFileTime(&rawTime);
178     outTime = ((static_cast<uint64_t>(rawTime.dwHighDateTime) << UINT32_BIT_LENGTH) +
179         (static_cast<uint64_t>(rawTime.dwLowDateTime))) / MULTIPLES_BETWEEN_MICROSECONDS_AND_100_NANOSECONDS -
180         MICROSECONDS_OFFSET;
181     return E_OK;
182 }
183 
GetMonotonicRelativeTimeInMicrosecond(uint64_t & outTime)184 int GetMonotonicRelativeTimeInMicrosecond(uint64_t &outTime)
185 {
186     LARGE_INTEGER frequency;
187     LARGE_INTEGER rawTime;
188     if (!QueryPerformanceFrequency(&frequency)) {
189         LOGE("query performance frequency fail %d", errno);
190         return -E_SYSTEM_API_FAIL;
191     }
192 
193     if (frequency.QuadPart == 0) {
194         LOGE("frequency quadpart zero!");
195         return -E_SYSTEM_API_FAIL;
196     }
197 
198     if (!QueryPerformanceCounter(&rawTime)) {
199         LOGE("query frequency counter fail %d!", errno);
200         return -E_SYSTEM_API_FAIL;
201     }
202 
203     outTime = (static_cast<uint64_t>(rawTime.QuadPart) * MULTIPLES_BETWEEN_MICROSECONDS_AND_NANOSECONDS) /
204         static_cast<uint64_t>(frequency.QuadPart);
205     return E_OK;
206 }
207 
InitFileType(const _finddata_t & file,FileAttr & fileAttr)208 static void InitFileType(const _finddata_t &file, FileAttr& fileAttr)
209 {
210     switch (file.attrib) {
211         case _A_NORMAL:
212         case _A_ARCH:
213             fileAttr.fileType = FILE;
214             return;
215         case _A_SUBDIR:
216             fileAttr.fileType = PATH;
217             return;
218         default:
219             fileAttr.fileType = OTHER;
220             return;
221     }
222 }
223 
GetFilePathAttr(const std::string & topPath,const std::string & relativePath,std::list<FileAttr> & files,bool isNeedAllPath)224 static int GetFilePathAttr(const std::string &topPath, const std::string &relativePath,
225     std::list<FileAttr> &files, bool isNeedAllPath)
226 {
227     _finddata_t file;
228     std::string findPath = std::string(topPath) + "\\*.*";
229     intptr_t handle = _findfirst(findPath.c_str(), &file);
230     if (handle < 0) {
231         LOGE("Open dir error:%s %d.", topPath.c_str(), errno);
232         return -E_INVALID_PATH;
233     }
234     int errCode = E_OK;
235     std::string fileAbsName;
236     struct _stat64 fileStat;
237     LOGE("find first file %s  %s relativePath %s", topPath.c_str(), file.name, relativePath.c_str());
238 
239     FileAttr fileAttr;
240     do {
241         InitFileType(file, fileAttr);
242 
243         if (strlen(file.name) == 0 || strcmp(file.name, ".") == 0 ||
244             strcmp(file.name, "..") == 0) {
245             continue;
246         }
247 
248         fileAttr.fileName = relativePath + file.name;
249         fileAbsName = topPath + "/" + file.name;
250         errCode = _stat64(fileAbsName.c_str(), &fileStat);
251         if (errCode != 0) {
252             LOGE("[GetFileAttr]Get file stat failed, %s error = %d.", fileAbsName.c_str(), errno);
253             errCode = -E_INVALID_PATH;
254             break;
255         }
256         if (isNeedAllPath) {
257             fileAttr.fileName = fileAbsName;
258         }
259         fileAttr.fileLen = static_cast<uint64_t>(fileStat.st_size);
260         files.push_back(fileAttr);
261         LOGE("find fileAbsName file %s %s %d relativePath %s", topPath.c_str(), file.name,
262              file.attrib, relativePath.c_str());
263         if (fileAttr.fileType == PATH) {
264             errCode = GetFilePathAttr(fileAbsName, relativePath + file.name + "/", files, isNeedAllPath);
265             if (errCode != E_OK) {
266                 LOGE("[GetFileAttr]GetFilePathAttr finish, %s error = %d.", topPath.c_str(), errCode);
267                 printf("GetFilePathAttr the finish %s error:%d\n", topPath.c_str(), errCode);
268                 break;
269             }
270         }
271     } while (_findnext(handle, &file) == 0);
272     _findclose(handle);
273     LOGE("[GetFileAttr]GetFilePathAttr finish, %s error = %d.", topPath.c_str(), errCode);
274     printf("GetFilePathAttr the finish end %s error:%d\n", topPath.c_str(), errCode);
275     return errCode;
276 }
277 
GetFileAttrFromPath(const std::string & filePath,std::list<FileAttr> & files,bool isNeedAllPath)278 int GetFileAttrFromPath(const std::string &filePath, std::list<FileAttr> &files, bool isNeedAllPath)
279 {
280     return GetFilePathAttr(filePath, std::string(), files, isNeedAllPath);
281 }
282 
GetFilePermissions(const std::string & fileName,uint32_t & permissions)283 int GetFilePermissions(const std::string &fileName, uint32_t &permissions)
284 {
285     struct _stat64 fileStat;
286     int errCode = _stat64(fileName.c_str(), &fileStat);
287     if (errCode != E_OK) {
288         permissions = _S_IREAD | _S_IWRITE;
289         LOGE("Get file stat failed, error = %d.", errno);
290         return -E_SYSTEM_API_FAIL;
291     }
292     permissions = fileStat.st_mode & (_S_IRWXU | _S_IFMT | _S_IFDIR | _S_IFCHR | _S_IFIFO | _S_IFREG);
293     return E_OK;
294 }
295 
SetFilePermissions(const std::string & fileName,uint32_t permissions)296 int SetFilePermissions(const std::string &fileName, uint32_t permissions)
297 {
298     if (permissions > (S_IRWXU | S_IRWXG | S_IRWXO)) {
299         return -E_INVALID_ARGS;
300     }
301     int errCode = _chmod(fileName.c_str(), _S_IREAD | _S_IWRITE);
302     if (errCode != E_OK) {
303         LOGE("Set file permissions failed, error = %d.", errno);
304         return -E_SYSTEM_API_FAIL;
305     }
306     return E_OK;
307 }
308 
OpenFile(const std::string & fileName,FileHandle * & handle)309 int OpenFile(const std::string &fileName, FileHandle *&handle)
310 {
311     handle = new (std::nothrow)FileHandle;
312     if (handle == nullptr) {
313         return -E_OUT_OF_MEMORY;
314     }
315     handle->handle = _open(fileName.c_str(), (O_WRONLY | O_CREAT), _S_IREAD | _S_IWRITE);
316     if (handle->handle < 0) {
317         LOGE("[FileLock] can not open file when lock it:[%d]", errno);
318         delete handle;
319         handle = nullptr;
320         return -E_SYSTEM_API_FAIL;
321     }
322     return E_OK;
323 }
324 
CloseFile(FileHandle * handle)325 int CloseFile(FileHandle *handle)
326 {
327     if (handle == nullptr || handle->handle == -1) {
328         LOGI("[CloseFile] file handle is invalid!");
329         return -E_INVALID_ARGS;
330     }
331 
332     if (close(handle->handle) != 0) {
333         LOGE("close file failed, errno:%d", errno);
334         return -E_SYSTEM_API_FAIL;
335     }
336     delete handle;
337     return E_OK;
338 }
339 
FileLock(const FileHandle * handle,bool isBlock)340 int FileLock(const FileHandle *handle, bool isBlock)
341 {
342     if (handle == nullptr) {
343         return -E_INVALID_ARGS;
344     }
345     if (handle->handle < 0) {
346         LOGE("[FileLock] can not open file when lock it:[%d]", errno);
347         return -E_SYSTEM_API_FAIL;
348     }
349     // windows下的LockFile与Linux差异较大,先不替换
350     return E_OK;
351 }
352 
FileUnlock(FileHandle * handle)353 int FileUnlock(FileHandle *handle)
354 {
355     return E_OK;
356 }
357 #else
358 namespace {
359     const int ACCESS_MODE_EXISTENCE = 0;
360     const uint64_t MULTIPLES_BETWEEN_SECONDS_AND_MICROSECONDS = 1000000;
361 }
362 
363 struct FileHandle {
364     int handle = -1;
365 };
366 
367 bool CheckPathExistence(const std::string &filePath)
368 {
369     return (access(filePath.c_str(), ACCESS_MODE_EXISTENCE) == 0);
370 }
371 
372 int RenameFilePath(const std::string &oldFilePath, const std::string &newFilePath)
373 {
374     int errCode = rename(oldFilePath.c_str(), newFilePath.c_str());
375     if (errCode < 0) {
376         LOGE("[Rename] Rename file fail. err = %d", errno);
377         return -E_SYSTEM_API_FAIL;
378     }
379     LOGI("Rename file path successfully!");
380     return E_OK;
381 }
382 
383 int RemoveFile(const std::string &filePath)
384 {
385     int errCode = remove(filePath.c_str());
386     if (errCode < 0) {
387         LOGE("[RemoveFile] Remove file fail. err = %d", errno);
388         return -E_SYSTEM_API_FAIL;
389     }
390     LOGI("Remove file successfully!");
391     return E_OK;
392 }
393 
394 int CalFileSize(const std::string &fileUrl, uint64_t &size)
395 {
396     struct stat fileStat;
397     if (fileUrl.empty() || stat(fileUrl.c_str(), &fileStat) < 0 || fileStat.st_size < 0) {
398         int errCode = (errno == ENOENT) ? -E_NOT_FOUND : -E_INVALID_DB;
399         LOGD("Get file[%zu] size failed, errno [%d].", fileUrl.size(), errno);
400         return errCode;
401     }
402 
403     size = static_cast<uint64_t>(fileStat.st_size);
404     return E_OK;
405 }
406 
407 void SplitFilePath(const std::string &filePath, std::string &fileDir, std::string &fileName)
408 {
409     if (filePath.empty()) {
410         return;
411     }
412 
413     auto slashPos = filePath.find_last_of('/');
414     if (slashPos == std::string::npos) {
415         fileName = filePath;
416         fileDir = "";
417         return;
418     }
419 
420     fileDir = filePath.substr(0, slashPos);
421     fileName = filePath.substr(slashPos + 1);
422     return;
423 }
424 
425 int MakeDBDirectory(const std::string &directory)
426 {
427     int errCode = mkdir(directory.c_str(), (S_IRWXU | S_IRWXG)); // The permission is 770 for linux based os
428     if (errCode < 0) {
429         LOGE("[MakeDir] Make directory fail:%d.", errno);
430         return -E_SYSTEM_API_FAIL;
431     }
432     return E_OK;
433 }
434 
435 int RemoveDBDirectory(const std::string &directory)
436 {
437     return remove(directory.c_str());
438 }
439 
440 int CreateFileByFileName(const std::string &fileName)
441 {
442     int fp = open(fileName.c_str(), (O_WRONLY | O_CREAT), (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP));
443     if (fp < 0) {
444         LOGE("[CreateFile] Create file fail:%d.", errno);
445         return -E_SYSTEM_API_FAIL;
446     }
447     close(fp);
448     return E_OK;
449 }
450 
451 int GetRealPath(const std::string &inOriPath, std::string &outRealPath)
452 {
453     const unsigned int MAX_PATH_LENGTH = PATH_MAX;
454     if (inOriPath.length() > MAX_PATH_LENGTH || MAX_PATH_LENGTH > 0x10000) { // max limit is 64K(0x10000).
455         LOGE("[RealPath] OriPath too long.");
456         return -E_INVALID_ARGS;
457     }
458 
459     char *realPath = new (std::nothrow) char[MAX_PATH_LENGTH + 1];
460     if (realPath == nullptr) {
461         return -E_OUT_OF_MEMORY;
462     }
463     if (memset_s(realPath, MAX_PATH_LENGTH + 1, 0, MAX_PATH_LENGTH + 1) != EOK) {
464         delete []realPath;
465         return -E_SECUREC_ERROR;
466     }
467 
468     if (realpath(inOriPath.c_str(), realPath) == nullptr) {
469         LOGE("[OS] Realpath error:%d.", errno);
470         delete []realPath;
471         return -E_SYSTEM_API_FAIL;
472     }
473     outRealPath = std::string(realPath);
474     delete []realPath;
475     return E_OK;
476 }
477 
478 #ifndef RUNNING_ON_SIMULATED_ENV
479 int GetCurrentSysTimeInMicrosecond(uint64_t &outTime)
480 {
481     struct timeval rawTime;
482     int errCode = gettimeofday(&rawTime, nullptr);
483     if (errCode < 0) {
484         LOGE("[GetSysTime] Fail:%d.", errCode);
485         return -E_SYSTEM_API_FAIL;
486     }
487     outTime = static_cast<uint64_t>(rawTime.tv_sec) * MULTIPLES_BETWEEN_SECONDS_AND_MICROSECONDS +
488               static_cast<uint64_t>(rawTime.tv_usec);
489     return E_OK;
490 }
491 #endif // RUNNING_ON_SIMULATED_ENV
492 
493 namespace {
494     const uint64_t MULTIPLES_BETWEEN_MICROSECONDS_AND_NANOSECONDS = 1000;
495 }
496 
497 int GetMonotonicRelativeTimeInMicrosecond(uint64_t &outTime)
498 {
499     struct timespec rawTime;
500     clockid_t clockId = CLOCK_REALTIME;
501 #ifdef OS_TYPE_WINDOWS
502     clockId = CLOCK_BOOTTIME;
503 #endif
504 #ifdef OS_TYPE_MAC
505     clockId = CLOCK_UPTIME_RAW;
506 #endif
507     int errCode = clock_gettime(clockId, &rawTime);
508     if (errCode < 0) {
509         LOGE("[GetMonoTime] Fail.");
510         return -E_SYSTEM_API_FAIL;
511     }
512 
513     outTime = static_cast<uint64_t>(rawTime.tv_sec) * MULTIPLES_BETWEEN_SECONDS_AND_MICROSECONDS +
514               static_cast<uint64_t>(rawTime.tv_nsec) / MULTIPLES_BETWEEN_MICROSECONDS_AND_NANOSECONDS;
515     return E_OK;
516 }
517 
518 static int GetFilePathAttr(const std::string &topPath, const std::string &relativePath,
519                            std::list<FileAttr> &files, bool isNeedAllPath)
520 {
521     DIR *dir = opendir(topPath.c_str());
522     if (dir == nullptr) {
523         LOGE("Open dir error:%d.", errno);
524         return -E_INVALID_PATH;
525     }
526     struct stat fileStat;
527     std::string fileAbsName;
528     int errCode = E_OK;
529     FileAttr file;
530     for (struct dirent *fileDirInfo = readdir(dir); fileDirInfo != nullptr; fileDirInfo = readdir(dir)) {
531         switch (fileDirInfo->d_type) {
532             case DT_REG:
533                 file.fileType = FILE;
534                 break;
535             case DT_DIR:
536                 file.fileType = PATH;
537                 break;
538             default:
539                 file.fileType = OTHER;
540         }
541         if (strlen(fileDirInfo->d_name) == 0 || strcmp(fileDirInfo->d_name, ".") == 0 ||
542             strcmp(fileDirInfo->d_name, "..") == 0) {
543             continue;
544         }
545         file.fileName = relativePath + fileDirInfo->d_name;
546         fileAbsName = topPath + "/" + fileDirInfo->d_name;
547         errCode = stat(fileAbsName.c_str(), &fileStat);
548         if (errCode != 0) {
549             LOGE("[GetFileAttr]Get file stat failed, error = %d.", errno);
550             errCode = -E_INVALID_PATH;
551             break;
552         }
553         if (isNeedAllPath) {
554             file.fileName = fileAbsName;
555         }
556         file.fileLen = static_cast<uint64_t>(fileStat.st_size);
557         files.push_back(file);
558         if (file.fileType == PATH) {
559             errCode = GetFilePathAttr(fileAbsName, relativePath + fileDirInfo->d_name + "/", files, isNeedAllPath);
560             if (errCode != E_OK) {
561                 break;
562             }
563         }
564     }
565 
566     closedir(dir);
567     return errCode;
568 }
569 
570 int GetFileAttrFromPath(const std::string &filePath, std::list<FileAttr> &files, bool isNeedAllPath)
571 {
572     return GetFilePathAttr(filePath, std::string(), files, isNeedAllPath);
573 }
574 
575 int GetFilePermissions(const std::string &fileName, uint32_t &permissions)
576 {
577     struct stat fileStat;
578     int errCode = stat(fileName.c_str(), &fileStat);
579     if (errCode != E_OK) {
580         permissions = S_IRUSR | S_IWUSR;
581         LOGE("Get file stat failed, error = %d.", errno);
582         return -E_SYSTEM_API_FAIL;
583     }
584     permissions = fileStat.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO);
585     return E_OK;
586 }
587 
588 int SetFilePermissions(const std::string &fileName, uint32_t permissions)
589 {
590     if (permissions > (S_IRWXU | S_IRWXG | S_IRWXO)) {
591         return -E_INVALID_ARGS;
592     }
593     int errCode = chmod(fileName.c_str(), permissions);
594     if (errCode != E_OK) {
595         LOGE("Set file permissions failed, error = %d.", errno);
596         return -E_SYSTEM_API_FAIL;
597     }
598     return E_OK;
599 }
600 
601 int OpenFile(const std::string &fileName, FileHandle *&handle)
602 {
603     handle = new (std::nothrow)FileHandle;
604     if (handle == nullptr) {
605         return -E_OUT_OF_MEMORY;
606     }
607     handle->handle = open(fileName.c_str(), (O_WRONLY | O_CREAT), (S_IRUSR | S_IWUSR | S_IRGRP));
608     if (handle->handle < 0) {
609         LOGE("[FileLock] can not open file when lock it:[%d]", errno);
610         delete handle;
611         handle = nullptr;
612         return -E_SYSTEM_API_FAIL;
613     }
614     return E_OK;
615 }
616 
617 int CloseFile(FileHandle *handle)
618 {
619     if (handle == nullptr || handle->handle == -1) {
620         LOGI("[CloseFile] file handle is invalid!");
621         return -E_INVALID_ARGS;
622     }
623     if (close(handle->handle) != 0) {
624         LOGE("close file failed, errno:%d", errno);
625         return -E_SYSTEM_API_FAIL;
626     }
627     delete handle;
628     return E_OK;
629 }
630 
631 int FileLock(const FileHandle *handle, bool isBlock)
632 {
633     if (handle == nullptr) {
634         return -E_INVALID_ARGS;
635     }
636     if (handle->handle < 0) {
637         LOGE("[FileLock] can not open file when lock it:[%d]", errno);
638         return -E_SYSTEM_API_FAIL;
639     }
640 
641     struct flock fileLockInfo;
642     (void)memset_s(&fileLockInfo, sizeof(fileLockInfo), 0, sizeof(fileLockInfo));
643     fileLockInfo.l_type = F_WRLCK;
644     fileLockInfo.l_whence = SEEK_SET;
645     fileLockInfo.l_start = 0;
646     fileLockInfo.l_len = 0;
647     LOGD("Lock file isBlock[%d]", isBlock);
648     if (fcntl(handle->handle, isBlock ? F_SETLKW : F_SETLK, &fileLockInfo) == -1 && !isBlock) {
649         LOGD("Lock file is Blocked, please retry!");
650         return -E_BUSY;
651     }
652     LOGI("file locked! errno:%d", errno);
653     return E_OK;
654 }
655 
656 int FileUnlock(FileHandle *handle)
657 {
658     if (handle == nullptr || handle->handle == -1) {
659         LOGI("[FileUnlock] file handle is invalid!");
660         return E_OK;
661     }
662 
663     struct flock fileLockInfo;
664     (void)memset_s(&fileLockInfo, sizeof(fileLockInfo), 0, sizeof(fileLockInfo));
665     fileLockInfo.l_type = F_UNLCK;
666     fileLockInfo.l_whence = SEEK_SET;
667     fileLockInfo.l_start = 0;
668     fileLockInfo.l_len = 0;
669     if (fcntl(handle->handle, F_SETLK, &fileLockInfo) == -1) {
670         LOGE("Unlock file failed. errno:%d", errno);
671         return -E_SYSTEM_API_FAIL;
672     }
673     return E_OK;
674 }
675 #endif
676 } // namespace OS
677 } // namespace DistributedDB
678