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