• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

taosdata / TDengine / #3842

07 Apr 2025 11:21AM UTC coverage: 62.696% (-0.3%) from 63.027%
#3842

push

travis-ci

web-flow
merge: from main to 3.0 branch (#30679)

154855 of 315075 branches covered (49.15%)

Branch coverage included in aggregate %.

6 of 8 new or added lines in 5 files covered. (75.0%)

2309 existing lines in 130 files now uncovered.

240176 of 314995 relevant lines covered (76.25%)

19119980.29 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

77.44
/source/os/src/osFile.c
1
/*
2
 * Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
3
 *
4
 * This program is free software: you can use, redistribute, and/or modify
5
 * it under the terms of the GNU Affero General Public License, version 3
6
 * or later ("AGPL"), as published by the Free Software Foundation.
7
 *
8
 * This program is distributed in the hope that it will be useful, but WITHOUT
9
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10
 * FITNESS FOR A PARTICULAR PURPOSE.
11
 *
12
 * You should have received a copy of the GNU Affero General Public License
13
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14
 */
15
#define ALLOW_FORBID_FUNC
16
#include "os.h"
17
#include "osSemaphore.h"
18
#include "tdef.h"
19
#include "zlib.h"
20

21
#ifdef WINDOWS
22
#include <WinBase.h>
23
#include <io.h>
24
#include <ktmw32.h>
25
#include <windows.h>
26
#define F_OK 0
27
#define X_OK 1
28
#define W_OK 2
29
#define R_OK 4
30

31
#define _SEND_FILE_STEP_ 1024
32

33
#else
34
#include <fcntl.h>
35
#ifndef TD_ASTRA
36
#include <sys/file.h>
37

38
#if !defined(_TD_DARWIN_64)
39
#include <sys/sendfile.h>
40
#endif
41
#endif
42
#include <sys/stat.h>
43
#include <unistd.h>
44
#define LINUX_FILE_NO_TEXT_OPTION 0
45
#define O_TEXT                    LINUX_FILE_NO_TEXT_OPTION
46

47
#define _SEND_FILE_STEP_ 1000
48
#endif
49

50
typedef int32_t FileFd;
51

52
#ifdef WINDOWS
53
typedef struct TdFile {
54
  TdThreadRwlock rwlock;
55
  HANDLE         hFile;
56
  FILE          *fp;
57
  int32_t        tdFileOptions;
58
} TdFile;
59
#else
60
typedef struct TdFile {
61
  TdThreadRwlock rwlock;
62
  FileFd         fd;
63
  FILE          *fp;
64
} TdFile;
65
#endif  // WINDOWS
66

67
#define FILE_WITH_LOCK 1
68

69
#ifdef BUILD_WITH_RAND_ERR
70
#define STUB_RAND_IO_ERR(ret)                                \
71
  if (tsEnableRandErr && (tsRandErrScope & RAND_ERR_FILE)) { \
72
    uint32_t r = taosRand() % tsRandErrDivisor;              \
73
    if ((r + 1) <= tsRandErrChance) {                        \
74
      errno = EIO;                                           \
75
      terrno = TAOS_SYSTEM_ERROR(errno);                     \
76
      return (ret);                                          \
77
    }                                                        \
78
  }
79
#else
80
#define STUB_RAND_IO_ERR(ret)
81
#endif
82

83
void taosGetTmpfilePath(const char *inputTmpDir, const char *fileNamePrefix, char *dstPath) {
717,267✔
84
  if (inputTmpDir == NULL || fileNamePrefix == NULL) return;
717,267!
85
#ifdef WINDOWS
86

87
  char tmpPath[PATH_MAX];
88

89
  int32_t len = (int32_t)strlen(inputTmpDir);
90
  memcpy(tmpPath, inputTmpDir, len);
91

92
  if (tmpPath[len - 1] != '/' && tmpPath[len - 1] != '\\') {
93
    tmpPath[len++] = '\\';
94
  }
95

96
  snprintf(tmpPath + len, sizeof(tmpPath) - len, "%s%s%s", TD_TMP_FILE_PREFIX, fileNamePrefix, "-%d-%s");
97

98
  char rand[8] = {0};
99
  taosRandStr(rand, tListLen(rand) - 1);
100
  snprintf(dstPath, PATH_MAX, tmpPath, taosGetPId(), rand);
101

102
#else
103

104
  char    tmpPath[PATH_MAX];
105
  int32_t len = strlen(inputTmpDir);
717,697✔
106
  (void)memcpy(tmpPath, inputTmpDir, len);
717,697✔
107
  static uint64_t seqId = 0;
108

109
  if (tmpPath[len - 1] != '/') {
717,697✔
110
    tmpPath[len++] = '/';
1✔
111
  }
112

113
  snprintf(tmpPath + len, sizeof(tmpPath) - len, "%s%s%s", TD_TMP_FILE_PREFIX, fileNamePrefix, "-%d-%s");
717,697✔
114

115
  char rand[32] = {0};
717,697✔
116

117
  (void)snprintf(rand, sizeof(rand), "%" PRIu64, atomic_add_fetch_64(&seqId, 1));
717,697✔
118

119
  (void)snprintf(dstPath, PATH_MAX, tmpPath, taosGetPId(), rand);
718,224✔
120

121
#endif
122
}
123

124
int64_t taosCopyFile(const char *from, const char *to) {
189✔
125
  if (from == NULL || to == NULL) {
189✔
126
    terrno = TSDB_CODE_INVALID_PARA;
2✔
127
    return -1;
2✔
128
  }
129
#ifdef WINDOWS
130
  if (CopyFile(from, to, 0)) {
131
    return 1;
132
  } else {
133
    terrno = TAOS_SYSTEM_WINAPI_ERROR(GetLastError());
134
    return -1;
135
  }
136
#else
137
  char    buffer[4096];
138
  int64_t size = 0;
187✔
139
  int64_t bytes;
140
  int32_t code = TSDB_CODE_SUCCESS;
187✔
141

142
  TdFilePtr pFileFrom = NULL;
187✔
143
  TdFilePtr pFileTo = NULL;
187✔
144
  pFileFrom = taosOpenFile(from, TD_FILE_READ);
187✔
145
  if (pFileFrom == NULL) {
187✔
146
    code = terrno;
1✔
147
    goto _err;
1✔
148
  }
149

150
  pFileTo = taosOpenFile(to, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_EXCL);
186✔
151
  if (pFileTo == NULL) {
186✔
152
    code = terrno;
1✔
153
    goto _err;
1✔
154
  }
155

156
  while (true) {
157
    bytes = taosReadFile(pFileFrom, buffer, sizeof(buffer));
195✔
158
    if (bytes < 0) {
195!
159
      code = terrno;
×
160
      goto _err;
×
161
    }
162

163
    if (bytes == 0) break;
195!
164

165
    size += bytes;
195✔
166

167
    if (taosWriteFile(pFileTo, (void *)buffer, bytes) < bytes) {
195!
168
      code = terrno;
×
169
      goto _err;
×
170
    }
171
    if (bytes < sizeof(buffer)) break;
195✔
172
  }
173

174
  code = taosFsyncFile(pFileTo);
185✔
175
  if (code != 0) {
185!
176
    goto _err;
×
177
  }
178

179
  TAOS_UNUSED(taosCloseFile(&pFileFrom));
185✔
180
  TAOS_UNUSED(taosCloseFile(&pFileTo));
185✔
181

182
  if (code != 0) {
185!
183
    terrno = code;
×
184
    return -1;
×
185
  }
186

187
  return size;
185✔
188

189
_err:
2✔
190

191
  if (pFileFrom != NULL) TAOS_SKIP_ERROR(taosCloseFile(&pFileFrom));
2✔
192
  if (pFileTo != NULL) TAOS_SKIP_ERROR(taosCloseFile(&pFileTo));
2!
193
  /* coverity[+retval] */
194
  TAOS_SKIP_ERROR(taosRemoveFile(to));
2✔
195

196
  terrno = code;
2✔
197
  return -1;
2✔
198
#endif
199
}
200

201
TdFilePtr taosCreateFile(const char *path, int32_t tdFileOptions) {
18✔
202
  if (path == NULL) {
18✔
203
    terrno = TSDB_CODE_INVALID_PARA;
1✔
204
    return NULL;
1✔
205
  }
206
  TdFilePtr fp = taosOpenFile(path, tdFileOptions);
17✔
207
  if (!fp) {
17✔
208
    if (terrno == TAOS_SYSTEM_ERROR(ENOENT)) {
1!
209
      // Try to create directory recursively
210
      char s[PATH_MAX];
211
      tstrncpy(s, path, sizeof(s));
1✔
212
      if (taosMulMkDir(taosDirName(s)) != 0) {
1!
213
        return NULL;
1✔
214
      }
215
      fp = taosOpenFile(path, tdFileOptions);
×
216
      if (!fp) {
×
217
        return NULL;
×
218
      }
219
    }
220
  }
221

222
  return fp;
16✔
223
}
224

225
int32_t taosRemoveFile(const char *path) {
1,015,998✔
226
  OS_PARAM_CHECK(path);
1,015,998✔
227
  int32_t code = remove(path);
1,015,997✔
228
  if (-1 == code) {
1,016,022✔
229
    terrno = TAOS_SYSTEM_ERROR(ERRNO);
718,269✔
230
    return terrno;
718,279✔
231
  }
232
  return code;
297,753✔
233
}
234

235
int32_t taosRenameFile(const char *oldName, const char *newName) {
255,449✔
236
  OS_PARAM_CHECK(oldName);
255,449✔
237
  OS_PARAM_CHECK(newName);
255,448✔
238
#ifdef WINDOWS
239
  bool finished = false;
240

241
  HANDLE transactionHandle = CreateTransaction(NULL, NULL, 0, 0, 0, INFINITE, NULL);
242
  if (transactionHandle == INVALID_HANDLE_VALUE) {
243
    DWORD error = GetLastError();
244
    terrno = TAOS_SYSTEM_WINAPI_ERROR(error);
245
    return terrno;
246
  }
247

248
  BOOL result = MoveFileTransacted(oldName, newName, NULL, NULL, MOVEFILE_REPLACE_EXISTING, transactionHandle);
249

250
  if (result) {
251
    finished = CommitTransaction(transactionHandle);
252
    if (!finished) {
253
      DWORD error = GetLastError();
254
      terrno = TAOS_SYSTEM_WINAPI_ERROR(error);
255
    }
256
  } else {
257
    RollbackTransaction(transactionHandle);
258
    DWORD error = GetLastError();
259
    terrno = TAOS_SYSTEM_WINAPI_ERROR(error);
260
    finished = false;
261
  }
262

263
  CloseHandle(transactionHandle);
264

265
  return finished ? 0 : terrno;
266
#else
267
#ifdef TD_ASTRA // TD_ASTRA_TODO
268
  if (taosCheckExistFile(newName)) taosRemoveFile(newName);
269
#endif
270
  int32_t code = rename(oldName, newName);
255,447✔
271
  if (-1 == code) {
255,443✔
272
    terrno = TAOS_SYSTEM_ERROR(ERRNO);
309✔
273
    return terrno;
308✔
274
  }
275

276
  return TSDB_CODE_SUCCESS;
255,134✔
277
#endif
278
}
279

280
int32_t taosStatFile(const char *path, int64_t *size, int64_t *mtime, int64_t *atime) {
495,050✔
281
  OS_PARAM_CHECK(path);
495,050✔
282
#ifdef WINDOWS
283
  struct _stati64 fileStat;
284
  int32_t         code = _stati64(path, &fileStat);
285
#else
286
  struct stat fileStat;
287
  int32_t     code = stat(path, &fileStat);
495,049✔
288
#endif
289
  if (-1 == code) {
495,021✔
290
    terrno = TAOS_SYSTEM_ERROR(ERRNO);
70,504✔
291
    return terrno;
70,554✔
292
  }
293

294
  if (size != NULL) {
424,517✔
295
    *size = fileStat.st_size;
393,660✔
296
  }
297

298
  if (mtime != NULL) {
424,517✔
299
    *mtime = fileStat.st_mtime;
17,507✔
300
  }
301

302
  if (atime != NULL) {
424,517!
303
    *atime = fileStat.st_atime;
×
304
  }
305

306
  return 0;
424,517✔
307
}
308

309
int32_t taosGetFileDiskID(const char *path, int64_t *diskid) {
2,248✔
310
  OS_PARAM_CHECK(path);
2,248✔
311
#ifdef WINDOWS
312
  struct _stati64 fileStat;
313
  int32_t         code = _stati64(path, &fileStat);
314
#else
315
  struct stat fileStat;
316
  int32_t     code = stat(path, &fileStat);
2,247✔
317
#endif
318
  if (-1 == code) {
2,247✔
319
    terrno = TAOS_SYSTEM_ERROR(ERRNO);
1✔
320
    return terrno;
1✔
321
  }
322

323
  if (diskid != NULL) {
2,246✔
324
    *diskid = fileStat.st_dev;
2,245✔
325
  }
326

327
  return 0;
2,246✔
328
}
329

330
int32_t taosDevInoFile(TdFilePtr pFile, int64_t *stDev, int64_t *stIno) {
37,339✔
331
#ifdef WINDOWS
332
  if (pFile == NULL || pFile->hFile == NULL) {
333
    terrno = TSDB_CODE_INVALID_PARA;
334
    return terrno;
335
  }
336
  BY_HANDLE_FILE_INFORMATION bhfi;
337
  if (GetFileInformationByHandle(pFile->hFile, &bhfi) == FALSE) {
338
    DWORD error = GetLastError();
339
    terrno = TAOS_SYSTEM_WINAPI_ERROR(error);
340
    return terrno;
341
  }
342

343
  if (stDev != NULL) {
344
    *stDev = (int64_t)(bhfi.dwVolumeSerialNumber);
345
  }
346

347
  if (stIno != NULL) {
348
    *stIno = (int64_t)((((uint64_t)bhfi.nFileIndexHigh) << 32) + bhfi.nFileIndexLow);
349
  }
350

351
#else
352
  if (pFile == NULL || pFile->fd < 0) {
37,339!
353
    terrno = TSDB_CODE_INVALID_PARA;
×
354
    return terrno;
1✔
355
  }
356

357
  struct stat fileStat;
358
  int32_t     code = fstat(pFile->fd, &fileStat);
37,358✔
359
  if (-1 == code) {
37,367!
360
    terrno = TAOS_SYSTEM_ERROR(ERRNO);
×
361
    return terrno;
×
362
  }
363

364
  if (stDev != NULL) {
37,400✔
365
    *stDev = fileStat.st_dev;
37,388✔
366
  }
367

368
  if (stIno != NULL) {
37,400!
369
    *stIno = fileStat.st_ino;
37,401✔
370
  }
371
#endif
372

373
  return 0;
37,400✔
374
}
375

376
FILE *taosOpenFileForStream(const char *path, int32_t tdFileOptions) {
17,052,156✔
377
  if (path == NULL) {
17,052,156✔
378
    terrno = TSDB_CODE_INVALID_PARA;
1✔
379
    return NULL;
1✔
380
  }
381
  char *mode = NULL;
17,052,155✔
382
  if (tdFileOptions & TD_FILE_APPEND) {
17,052,155✔
383
    mode = (tdFileOptions & TD_FILE_TEXT) ? "at+" : "ab+";
15,567!
384
  } else if (tdFileOptions & TD_FILE_TRUNC) {
17,036,588✔
385
    mode = (tdFileOptions & TD_FILE_TEXT) ? "wt+" : "wb+";
12,499✔
386
  } else if ((tdFileOptions & TD_FILE_READ) && !(tdFileOptions & TD_FILE_WRITE)) {
17,024,089!
387
    mode = (tdFileOptions & TD_FILE_TEXT) ? "rt" : "rb";
17,024,089!
388
  } else {
389
    mode = (tdFileOptions & TD_FILE_TEXT) ? "rt+" : "rb+";
×
390
  }
391
  if (tdFileOptions & TD_FILE_EXCL) {
17,052,155!
392
    terrno = TSDB_CODE_INVALID_PARA;
×
393
    return NULL;
×
394
  }
395
  FILE *f = fopen(path, mode);
17,052,155✔
396
  if (NULL == f) {
17,052,154✔
397
    terrno = TAOS_SYSTEM_ERROR(ERRNO);
41✔
398
  }
399
  return f;
17,052,155✔
400
}
401

402
#ifdef WINDOWS
403
HANDLE taosOpenFileNotStream(const char *path, int32_t tdFileOptions) {
404
  if (path == NULL) {
405
    terrno = TSDB_CODE_INVALID_PARA;
406
    return INVALID_HANDLE_VALUE;
407
  }
408
  DWORD openMode = 0;
409
  DWORD access = 0;
410
  DWORD fileFlag = FILE_ATTRIBUTE_NORMAL;
411
  DWORD shareMode = FILE_SHARE_READ;
412

413
  openMode = OPEN_EXISTING;
414
  if (tdFileOptions & TD_FILE_CREATE) {
415
    openMode = OPEN_ALWAYS;
416
  } else if (tdFileOptions & TD_FILE_EXCL) {
417
    openMode = CREATE_NEW;
418
  } else if ((tdFileOptions & TD_FILE_TRUNC)) {
419
    openMode = TRUNCATE_EXISTING;
420
    access |= GENERIC_WRITE;
421
  }
422
  if (tdFileOptions & TD_FILE_APPEND) {
423
    access |= FILE_APPEND_DATA;
424
  }
425
  if (tdFileOptions & TD_FILE_WRITE) {
426
    access |= GENERIC_WRITE;
427
  }
428

429
  shareMode |= FILE_SHARE_WRITE;
430

431
  access |= GENERIC_READ;
432

433
  if (tdFileOptions & TD_FILE_AUTO_DEL) {
434
    fileFlag |= FILE_ATTRIBUTE_TEMPORARY;
435
  }
436
  if (tdFileOptions & TD_FILE_WRITE_THROUGH) {
437
    fileFlag |= FILE_FLAG_WRITE_THROUGH;
438
  }
439

440
  HANDLE h = CreateFile(path, access, shareMode, NULL, openMode, fileFlag, NULL);
441
  if (h != INVALID_HANDLE_VALUE && (tdFileOptions & TD_FILE_APPEND) && (tdFileOptions & TD_FILE_WRITE)) {
442
    SetFilePointer(h, 0, NULL, FILE_END);
443
  }
444
  if (h == INVALID_HANDLE_VALUE) {
445
    DWORD dwError = GetLastError();
446
    terrno = TAOS_SYSTEM_WINAPI_ERROR(dwError);
447
    // LPVOID lpMsgBuf;
448
    // FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwError, 0, (LPTSTR)&lpMsgBuf,
449
    // 0,
450
    //               NULL);
451
    // printf("CreateFile failed with error %d: %s", dwError, (char *)lpMsgBuf);
452
    // LocalFree(lpMsgBuf);
453
  }
454
  return h;
455
}
456

457
int64_t taosReadFile(TdFilePtr pFile, void *buf, int64_t count) {
458
  if (pFile == NULL || buf == NULL) {
459
    terrno = TSDB_CODE_INVALID_PARA;
460
    return terrno;
461
  }
462
#if FILE_WITH_LOCK
463
  (void)taosThreadRwlockRdlock(&(pFile->rwlock));
464
#endif
465
  if (pFile->hFile == NULL) {
466
#if FILE_WITH_LOCK
467
    (void)taosThreadRwlockUnlock(&(pFile->rwlock));
468
#endif
469
    terrno = TSDB_CODE_INVALID_PARA;
470
    return terrno;
471
  }
472

473
  int64_t res = 0;
474
  DWORD   bytesRead;
475
  if (!ReadFile(pFile->hFile, buf, count, &bytesRead, NULL)) {
476
    DWORD errCode = GetLastError();
477
    terrno = TAOS_SYSTEM_WINAPI_ERROR(errCode);
478
    res = -1;
479
  } else {
480
    res = bytesRead;
481
  }
482
#if FILE_WITH_LOCK
483
  (void)taosThreadRwlockUnlock(&(pFile->rwlock));
484
#endif
485
  return res;
486
}
487

488
int64_t taosWriteFile(TdFilePtr pFile, const void *buf, int64_t count) {
489
  if (pFile == NULL || pFile->hFile == NULL || buf == NULL) {
490
    terrno = TSDB_CODE_INVALID_PARA;
491
    return 0;
492
  }
493
#if FILE_WITH_LOCK
494
  (void)taosThreadRwlockWrlock(&(pFile->rwlock));
495
#endif
496

497
  DWORD bytesWritten;
498
  if (!WriteFile(pFile->hFile, buf, count, &bytesWritten, NULL)) {
499
    SET_ERRNO(GetLastError());
500
    terrno = TAOS_SYSTEM_WINAPI_ERROR(ERRNO);
501
    bytesWritten = -1;
502
  }
503

504
#if FILE_WITH_LOCK
505
  (void)taosThreadRwlockUnlock(&(pFile->rwlock));
506
#endif
507
  return bytesWritten;
508
}
509

510
int64_t taosPWriteFile(TdFilePtr pFile, const void *buf, int64_t count, int64_t offset) {
511
  if (pFile == NULL || buf == NULL) {
512
    terrno = TSDB_CODE_INVALID_PARA;
513
    return 0;
514
  }
515
#if FILE_WITH_LOCK
516
  (void)taosThreadRwlockWrlock(&(pFile->rwlock));
517
#endif
518
  if (pFile->hFile == NULL) {
519
#if FILE_WITH_LOCK
520
    (void)taosThreadRwlockUnlock(&(pFile->rwlock));
521
#endif
522
    return 0;
523
  }
524

525
  DWORD      ret = 0;
526
  OVERLAPPED ol = {0};
527
  ol.OffsetHigh = (uint32_t)((offset & 0xFFFFFFFF00000000LL) >> 0x20);
528
  ol.Offset = (uint32_t)(offset & 0xFFFFFFFFLL);
529

530
  SetLastError(0);
531
  BOOL result = WriteFile(pFile->hFile, buf, count, &ret, &ol);
532
  if (!result) {
533
    SET_ERRNO(GetLastError());
534
    terrno = TAOS_SYSTEM_WINAPI_ERROR(ERRNO);
535
    ret = -1;
536
  }
537

538
#if FILE_WITH_LOCK
539
  (void)taosThreadRwlockUnlock(&(pFile->rwlock));
540
#endif
541
  return ret;
542
}
543

544
int64_t taosLSeekFile(TdFilePtr pFile, int64_t offset, int32_t whence) {
545
  if (pFile == NULL || pFile->hFile == NULL) {
546
    terrno = TSDB_CODE_INVALID_PARA;
547
    return -1;
548
  }
549
#if FILE_WITH_LOCK
550
  (void)taosThreadRwlockRdlock(&(pFile->rwlock));
551
#endif
552

553
  LARGE_INTEGER liOffset;
554
  liOffset.QuadPart = offset;
555
  if (!SetFilePointerEx(pFile->hFile, liOffset, NULL, whence)) {
556
    SET_ERRNO(GetLastError());
557
    terrno = TAOS_SYSTEM_WINAPI_ERROR(ERRNO);
558
    return -1;
559
  }
560

561
  liOffset.QuadPart = 0;
562
  if (!SetFilePointerEx(pFile->hFile, liOffset, &liOffset, FILE_CURRENT)) {
563
    SET_ERRNO(GetLastError());
564
    terrno = TAOS_SYSTEM_WINAPI_ERROR(ERRNO);
565
    return -1;
566
  }
567
#if FILE_WITH_LOCK
568
  (void)taosThreadRwlockUnlock(&(pFile->rwlock));
569
#endif
570
  return liOffset.QuadPart;
571
}
572

573
int32_t taosFStatFile(TdFilePtr pFile, int64_t *size, int64_t *mtime) {
574
  if (pFile == NULL || pFile->hFile == NULL) {
575
    terrno = TSDB_CODE_INVALID_PARA;
576
    return terrno;
577
  }
578

579
  if (size != NULL) {
580
    LARGE_INTEGER fileSize;
581
    if (!GetFileSizeEx(pFile->hFile, &fileSize)) {
582
      SET_ERRNO(GetLastError());
583
      terrno = TAOS_SYSTEM_WINAPI_ERROR(ERRNO);
584
      return terrno;  // Error getting file size
585
    }
586
    *size = fileSize.QuadPart;
587
  }
588

589
  if (mtime != NULL) {
590
    FILETIME creationTime, lastAccessTime, lastWriteTime;
591
    if (!GetFileTime(pFile->hFile, &creationTime, &lastAccessTime, &lastWriteTime)) {
592
      SET_ERRNO(GetLastError());
593
      terrno = TAOS_SYSTEM_WINAPI_ERROR(ERRNO);
594
      return terrno;  // Error getting file time
595
    }
596
    // Convert the FILETIME structure to a time_t value
597
    ULARGE_INTEGER ull;
598
    ull.LowPart = lastWriteTime.dwLowDateTime;
599
    ull.HighPart = lastWriteTime.dwHighDateTime;
600
    *mtime = (int64_t)((ull.QuadPart - 116444736000000000ULL) / 10000000ULL);
601
  }
602
  return 0;
603
}
604

605
int32_t taosLockFile(TdFilePtr pFile) {
606
  if (pFile == NULL || pFile->hFile == NULL) {
607
    terrno = TSDB_CODE_INVALID_PARA;
608
    return terrno;
609
  }
610

611
  BOOL          fSuccess = FALSE;
612
  LARGE_INTEGER fileSize;
613
  OVERLAPPED    overlapped = {0};
614

615
  fSuccess = LockFileEx(pFile->hFile, LOCKFILE_EXCLUSIVE_LOCK | LOCKFILE_FAIL_IMMEDIATELY,
616
                        0,           // reserved
617
                        ~0,          // number of bytes to lock low
618
                        ~0,          // number of bytes to lock high
619
                        &overlapped  // overlapped structure
620
  );
621
  if (!fSuccess) {
622
    return TAOS_SYSTEM_WINAPI_ERROR(GetLastError());
623
  }
624
  return 0;
625
}
626

627
int32_t taosUnLockFile(TdFilePtr pFile) {
628
  if (pFile == NULL || pFile->hFile == NULL) {
629
    return 0;
630
  }
631
  BOOL       fSuccess = FALSE;
632
  OVERLAPPED overlapped = {0};
633

634
  fSuccess = UnlockFileEx(pFile->hFile, 0, ~0, ~0, &overlapped);
635
  if (!fSuccess) {
636
    return TAOS_SYSTEM_WINAPI_ERROR(GetLastError());
637
  }
638
  return 0;
639
}
640

641
int32_t taosFtruncateFile(TdFilePtr pFile, int64_t l_size) {
642
  if (pFile == NULL) {
643
    terrno = TSDB_CODE_INVALID_PARA;
644
    return terrno;
645
  }
646
  if (pFile->hFile == NULL) {
647
    printf("Ftruncate file error, hFile was null\n");
648
    terrno = TSDB_CODE_INVALID_PARA;
649
    return terrno;
650
  }
651

652
  LARGE_INTEGER li_0;
653
  li_0.QuadPart = (int64_t)0;
654
  BOOL cur = SetFilePointerEx(pFile->hFile, li_0, NULL, FILE_CURRENT);
655
  if (!cur) {
656
    printf("SetFilePointerEx Error getting current position in file.\n");
657
    terrno = TAOS_SYSTEM_WINAPI_ERROR(GetLastError());
658
    return terrno;
659
  }
660

661
  LARGE_INTEGER li_size;
662
  li_size.QuadPart = l_size;
663
  BOOL cur2 = SetFilePointerEx(pFile->hFile, li_size, NULL, FILE_BEGIN);
664
  if (cur2 == 0) {
665
    int error = GetLastError();
666
    switch (error) {
667
      case ERROR_INVALID_HANDLE:
668
        SET_ERRNO(EBADF);
669
        break;
670
      default:
671
        SET_ERRNO(EIO);
672
        break;
673
    }
674
    terrno = TAOS_SYSTEM_ERROR(ERRNO);
675
    return terrno;
676
  }
677

678
  if (!SetEndOfFile(pFile->hFile)) {
679
    int error = GetLastError();
680
    printf("SetEndOfFile GetLastError is:%d", error);
681
    switch (error) {
682
      case ERROR_INVALID_HANDLE:
683
        SET_ERRNO(EBADF);
684
        break;
685
      default:
686
        SET_ERRNO(EIO);
687
        break;
688
    }
689
    terrno = TAOS_SYSTEM_ERROR(ERRNO);
690
    return terrno;
691
  }
692
  return 0;
693
}
694

695
int64_t taosFSendFile(TdFilePtr pFileOut, TdFilePtr pFileIn, int64_t *offset, int64_t size) {
696
  if (pFileOut == NULL || pFileIn == NULL) {
697
    terrno = TSDB_CODE_INVALID_PARA;
698
    return -1;
699
  }
700
  if (pFileIn->hFile == NULL || pFileOut->hFile == NULL) {
701
    terrno = TSDB_CODE_INVALID_PARA;
702
    return -1;
703
  }
704

705
  LARGE_INTEGER fileOffset;
706
  fileOffset.QuadPart = *offset;
707

708
  if (!SetFilePointerEx(pFileIn->hFile, fileOffset, &fileOffset, FILE_BEGIN)) {
709
    terrno = TAOS_SYSTEM_WINAPI_ERROR(GetLastError());
710
    return -1;
711
  }
712

713
  int64_t writeLen = 0;
714
  uint8_t buffer[_SEND_FILE_STEP_] = {0};
715

716
  DWORD bytesRead;
717
  DWORD bytesWritten;
718
  for (int64_t len = 0; len < (size - _SEND_FILE_STEP_); len += _SEND_FILE_STEP_) {
719
    if (!ReadFile(pFileIn->hFile, buffer, _SEND_FILE_STEP_, &bytesRead, NULL)) {
720
      terrno = TAOS_SYSTEM_WINAPI_ERROR(GetLastError());
721
      return writeLen;
722
    }
723

724
    if (bytesRead <= 0) {
725
      return writeLen;
726
    } else if (bytesRead < _SEND_FILE_STEP_) {
727
      if (!WriteFile(pFileOut->hFile, buffer, bytesRead, &bytesWritten, NULL)) {
728
        terrno = TAOS_SYSTEM_WINAPI_ERROR(GetLastError());
729
        return -1;
730
      } else {
731
        return (int64_t)(writeLen + bytesRead);
732
      }
733
    } else {
734
      if (!WriteFile(pFileOut->hFile, buffer, _SEND_FILE_STEP_, &bytesWritten, NULL)) {
735
        terrno = TAOS_SYSTEM_WINAPI_ERROR(GetLastError());
736
        return -1;
737
      } else {
738
        writeLen += _SEND_FILE_STEP_;
739
      }
740
    }
741
  }
742

743
  int64_t remain = size - writeLen;
744
  if (remain > 0) {
745
    DWORD bytesRead;
746
    if (!ReadFile(pFileIn->hFile, buffer, (DWORD)remain, &bytesRead, NULL)) {
747
      terrno = TAOS_SYSTEM_WINAPI_ERROR(GetLastError());
748
      return -1;
749
    }
750

751
    if (bytesRead <= 0) {
752
      return writeLen;
753
    } else {
754
      DWORD bytesWritten;
755
      if (!WriteFile(pFileOut->hFile, buffer, bytesRead, &bytesWritten, NULL)) {
756
        terrno = TAOS_SYSTEM_WINAPI_ERROR(GetLastError());
757
        return -1;
758
      } else {
759
        writeLen += bytesWritten;
760
      }
761
    }
762
  }
763
  return writeLen;
764
}
765

766
bool lastErrorIsFileNotExist() {
767
  DWORD dwError = GetLastError();
768
  return dwError == ERROR_FILE_NOT_FOUND;
769
}
770

771
#else
772
int taosOpenFileNotStream(const char *path, int32_t tdFileOptions) {
19,482,715✔
773
  if (path == NULL) {
19,482,715!
774
    terrno = TSDB_CODE_INVALID_PARA;
×
775
    return -1;
×
776
  }
777
  int access = O_BINARY;
19,482,715✔
778
  access |= (tdFileOptions & TD_FILE_CREATE) ? O_CREAT : 0;
19,482,715✔
779
  if ((tdFileOptions & TD_FILE_WRITE) && (tdFileOptions & TD_FILE_READ)) {
19,482,715✔
780
    access |= O_RDWR;
885,077✔
781
  } else if (tdFileOptions & TD_FILE_WRITE) {
18,597,638✔
782
    access |= O_WRONLY;
345,007✔
783
  } else if (tdFileOptions & TD_FILE_READ) {
18,252,631!
784
    access |= O_RDONLY;
18,259,930✔
785
  }
786
  access |= (tdFileOptions & TD_FILE_TRUNC) ? O_TRUNC : 0;
19,482,715✔
787
  access |= (tdFileOptions & TD_FILE_APPEND) ? O_APPEND : 0;
19,482,715✔
788
  access |= (tdFileOptions & TD_FILE_TEXT) ? O_TEXT : 0;
19,482,715✔
789
  access |= (tdFileOptions & TD_FILE_EXCL) ? O_EXCL : 0;
19,482,715✔
790
  access |= (tdFileOptions & TD_FILE_CLOEXEC) ? O_CLOEXEC : 0;
19,482,715✔
791

792
  int fd = open(path, access, S_IRWXU | S_IRWXG | S_IRWXO);
19,482,715✔
793
  if (-1 == fd) {
19,491,708✔
794
    terrno = TAOS_SYSTEM_ERROR(ERRNO);
53,354✔
795
  }
796
  return fd;
19,489,931✔
797
}
798

799
int64_t taosReadFile(TdFilePtr pFile, void *buf, int64_t count) {
53,395,586✔
800
  if (pFile == NULL || buf == NULL) {
53,395,586!
801
    terrno = TSDB_CODE_INVALID_PARA;
×
802
    return -1;
2✔
803
  }
804
  STUB_RAND_IO_ERR(terrno)
805
#if FILE_WITH_LOCK
806
  (void)taosThreadRwlockRdlock(&(pFile->rwlock));
53,402,524✔
807
#endif
808

809
  if (pFile->fd < 0) {
53,411,709✔
810
#if FILE_WITH_LOCK
811
    (void)taosThreadRwlockUnlock(&(pFile->rwlock));
374✔
812
#endif
813
    terrno = TSDB_CODE_INVALID_PARA;
×
814
    return -1;
×
815
  }
816

817
  int64_t leftbytes = count;
53,411,335✔
818
  int64_t readbytes;
819
  char   *tbuf = (char *)buf;
53,411,335✔
820
  int32_t code = 0;
53,411,335✔
821

822
  while (leftbytes > 0) {
106,810,613✔
823
#ifdef WINDOWS
824
    readbytes = _read(pFile->fd, (void *)tbuf, (uint32_t)leftbytes);
825
#else
826
    readbytes = read(pFile->fd, (void *)tbuf, (uint32_t)leftbytes);
53,403,437✔
827
#endif
828
    if (readbytes < 0) {
53,404,068✔
829
      if (ERRNO == EINTR) {
113!
830
        continue;
×
831
      } else {
832
        code = TAOS_SYSTEM_ERROR(ERRNO);
113✔
833
#if FILE_WITH_LOCK
834
        (void)taosThreadRwlockUnlock(&(pFile->rwlock));
113✔
835
#endif
836
        terrno = code;
113✔
837
        return -1;
113✔
838
      }
839
    } else if (readbytes == 0) {
53,403,955✔
840
#if FILE_WITH_LOCK
841
      (void)taosThreadRwlockUnlock(&(pFile->rwlock));
4,677✔
842
#endif
843
      return (int64_t)(count - leftbytes);
4,677✔
844
    }
845

846
    leftbytes -= readbytes;
53,399,278✔
847
    tbuf += readbytes;
53,399,278✔
848
  }
849

850
#if FILE_WITH_LOCK
851
  (void)taosThreadRwlockUnlock(&(pFile->rwlock));
53,407,176✔
852
#endif
853

854
  return count;
53,408,665✔
855
}
856

857
int64_t taosWriteFile(TdFilePtr pFile, const void *buf, int64_t count) {
778,967,187✔
858
  STUB_RAND_IO_ERR(terrno)
859
  if (pFile == NULL || buf == NULL) {
778,967,187!
860
    terrno = TSDB_CODE_INVALID_PARA;
×
861
    return 0;
2✔
862
  }
863
#if FILE_WITH_LOCK
864
  (void)taosThreadRwlockWrlock(&(pFile->rwlock));
779,016,366✔
865
#endif
866
  if (pFile->fd < 0) {
779,261,437!
867
#if FILE_WITH_LOCK
868
    (void)taosThreadRwlockUnlock(&(pFile->rwlock));
×
869
#endif
870
    terrno = TSDB_CODE_INVALID_PARA;
×
871
    return 0;
×
872
  }
873

874
  int64_t nleft = count;
779,261,439✔
875
  int64_t nwritten = 0;
779,261,439✔
876
  char   *tbuf = (char *)buf;
779,261,439✔
877
  int32_t code = 0;
779,261,439✔
878

879
  while (nleft > 0) {
1,558,518,069✔
880
    nwritten = write(pFile->fd, (void *)tbuf, (uint32_t)nleft);
779,260,540✔
881
    if (nwritten < 0) {
779,256,631✔
882
      if (ERRNO == EINTR) {
1!
883
        continue;
×
884
      }
885
      code = TAOS_SYSTEM_ERROR(ERRNO);
1✔
886
#if FILE_WITH_LOCK
887
      (void)taosThreadRwlockUnlock(&(pFile->rwlock));
1✔
888
#endif
889
      terrno = code;
1✔
890
      return -1;
1✔
891
    }
892
    nleft -= nwritten;
779,256,630✔
893
    tbuf += nwritten;
779,256,630✔
894
  }
895

896
#if FILE_WITH_LOCK
897
  (void)taosThreadRwlockUnlock(&(pFile->rwlock));
779,257,529✔
898
#endif
899

900
  return count;
779,207,166✔
901
}
902

903
int64_t taosPWriteFile(TdFilePtr pFile, const void *buf, int64_t count, int64_t offset) {
1,104,333✔
904
  STUB_RAND_IO_ERR(terrno)
905
  if (pFile == NULL || buf == NULL) {
1,104,333!
906
    terrno = TSDB_CODE_INVALID_PARA;
×
907
    return 0;
2✔
908
  }
909

910
  int32_t code = 0;
1,104,351✔
911
#if FILE_WITH_LOCK
912
  (void)taosThreadRwlockWrlock(&(pFile->rwlock));
1,104,351✔
913
#endif
914

915
#if FILE_WITH_LOCK
916
  if (pFile->fd < 0) {
1,104,748!
917
    (void)taosThreadRwlockUnlock(&(pFile->rwlock));
×
918
    return 0;
×
919
  }
920
#endif
921
#ifndef TD_ASTRA
922
  int64_t ret = pwrite(pFile->fd, buf, count, offset);
1,104,748✔
923
  if (-1 == ret) {
1,104,264!
924
    code = TAOS_SYSTEM_ERROR(ERRNO);
×
925
  }
926
#else  // TD_ASTRA_TODO
927
  int64_t ret = -1;
928
  int64_t cur = lseek(pFile->fd, 0, SEEK_CUR);
929
  if (cur < 0) {
930
    code = TAOS_SYSTEM_ERROR(ERRNO);
931
    goto _exit;
932
  }
933
  if (lseek(pFile->fd, offset, SEEK_SET) < 0) {
934
    code = TAOS_SYSTEM_ERROR(ERRNO);
935
    goto _exit;
936
  }
937
  if ((ret = write(pFile->fd, buf, count)) < 0) {
938
    code = TAOS_SYSTEM_ERROR(ERRNO);
939
    goto _exit;
940
  }
941
_exit:
942
  if (cur >= 0 && lseek(pFile->fd, cur, SEEK_SET) < 0) {
943
    code = TAOS_SYSTEM_ERROR(ERRNO);
944
  }
945
#endif
946
#if FILE_WITH_LOCK
947
  (void)taosThreadRwlockUnlock(&(pFile->rwlock));
1,104,264✔
948
#endif
949

950
  if (code) {
1,104,593!
951
    terrno = code;
×
952
  }
953

954
  return ret;
1,104,645✔
955
}
956

957
int64_t taosLSeekFile(TdFilePtr pFile, int64_t offset, int32_t whence) {
69,387,948✔
958
  if (pFile == NULL || pFile->fd < 0) {
69,387,948!
959
    terrno = TSDB_CODE_INVALID_PARA;
×
960
    return -1;
1✔
961
  }
962
#if FILE_WITH_LOCK
963
  (void)taosThreadRwlockRdlock(&(pFile->rwlock));
69,397,259✔
964
#endif
965

966
  int32_t code = 0;
69,410,864✔
967

968
  int64_t ret = lseek(pFile->fd, offset, whence);
69,410,864✔
969
  if (-1 == ret) {
69,408,070!
970
    code = TAOS_SYSTEM_ERROR(ERRNO);
×
971
  }
972

973
#if FILE_WITH_LOCK
974
  (void)taosThreadRwlockUnlock(&(pFile->rwlock));
69,408,070✔
975
#endif
976

977
  if (code) {
69,404,886!
UNCOV
978
    terrno = code;
×
979
    return -1;
×
980
  }
981

982
  return ret;
69,405,991✔
983
}
984

985
int32_t taosFStatFile(TdFilePtr pFile, int64_t *size, int64_t *mtime) {
108,662✔
986
  if (pFile == NULL) {
108,662✔
987
    terrno = TSDB_CODE_INVALID_PARA;
2✔
988
    return terrno;
2✔
989
  }
990

991
  if (pFile->fd < 0) {
108,660!
992
    terrno = TSDB_CODE_INVALID_PARA;
×
993
    return terrno;
×
994
  }
995

996
  struct stat fileStat;
997
  int32_t     code = fstat(pFile->fd, &fileStat);
108,660✔
998
  if (-1 == code) {
108,678!
UNCOV
999
    terrno = TAOS_SYSTEM_ERROR(ERRNO);
×
1000
    return terrno;
×
1001
  }
1002

1003
  if (size != NULL) {
108,690✔
1004
    *size = fileStat.st_size;
108,682✔
1005
  }
1006

1007
  if (mtime != NULL) {
108,690!
1008
    *mtime = fileStat.st_mtime;
×
1009
  }
1010

1011
  return 0;
108,690✔
1012
}
1013

1014
int32_t taosLockFile(TdFilePtr pFile) {
60,996✔
1015
  if (NULL == pFile || pFile->fd < 0) {
60,996!
1016
    terrno = TSDB_CODE_INVALID_PARA;
2✔
1017
    return terrno;
2✔
1018
  }
1019
#ifndef TD_ASTRA
1020
  int32_t code = (int32_t)flock(pFile->fd, LOCK_EX | LOCK_NB);
60,994✔
1021
  if (-1 == code) {
60,994✔
1022
    terrno = TAOS_SYSTEM_ERROR(ERRNO);
25,118✔
1023
    return terrno;
25,118✔
1024
  }
1025
#else // TD_ASTRA_TODO
1026
  struct flock lock;
1027
  lock.l_type = F_WRLCK;
1028
  lock.l_whence = SEEK_SET;
1029
  lock.l_start = 0;
1030
  lock.l_len = 0;
1031
  int32_t code = fcntl(pFile->fd, F_SETLK, &lock);
1032
  if (-1 == code) {
1033
    //    terrno = TAOS_SYSTEM_ERROR(ERRNO); // TD_ASTRA_TODO
1034
    //    return terrno;                     // TD_ASTRA_TODO
1035
  }
1036
#endif
1037
  return 0;
35,876✔
1038
}
1039

1040
int32_t taosUnLockFile(TdFilePtr pFile) {
18,539✔
1041
  if (NULL == pFile || pFile->fd < 0) {
18,539!
1042
    terrno = TSDB_CODE_INVALID_PARA;
2✔
1043
    return terrno;
2✔
1044
  }
1045
#ifndef TD_ASTRA
1046
  int32_t code = (int32_t)flock(pFile->fd, LOCK_UN | LOCK_NB);
18,537✔
1047
  if (-1 == code) {
18,537!
1048
    terrno = TAOS_SYSTEM_ERROR(ERRNO);
×
1049
    return terrno;
×
1050
  }
1051
#else // TD_ASTRA_TODO
1052
  struct flock lock;
1053
  lock.l_type = F_UNLCK;
1054
  lock.l_whence = SEEK_SET;
1055
  lock.l_start = 0;
1056
  lock.l_len = 0;
1057
  int32_t code = fcntl(pFile->fd, F_SETLK, &lock);
1058
  if (-1 == code) {
1059
    //    terrno = TAOS_SYSTEM_ERROR(ERRNO);// TD_ASTRA_TODO
1060
    //    return terrno;// TD_ASTRA_TODO
1061
  }
1062
#endif
1063
  return 0;
18,537✔
1064
}
1065

1066
int32_t taosFtruncateFile(TdFilePtr pFile, int64_t l_size) {
233✔
1067
  if (NULL == pFile || pFile->fd < 0) {
233!
1068
    terrno = TSDB_CODE_INVALID_PARA;
2✔
1069
    return terrno;
2✔
1070
  }
1071

1072
  int32_t code = ftruncate(pFile->fd, l_size);
231✔
1073
  if (-1 == code) {
231!
1074
    terrno = TAOS_SYSTEM_ERROR(ERRNO);
×
1075
    return terrno;
×
1076
  }
1077
  return 0;
231✔
1078
}
1079

1080
int64_t taosFSendFile(TdFilePtr pFileOut, TdFilePtr pFileIn, int64_t *offset, int64_t size) {
31✔
1081
  if (pFileOut == NULL || pFileIn == NULL) {
31✔
1082
    terrno = TSDB_CODE_INVALID_PARA;
3✔
1083
    return -1;
3✔
1084
  }
1085
  if (pFileIn->fd < 0 || pFileOut->fd < 0) {
28!
1086
    terrno = TSDB_CODE_INVALID_PARA;
×
1087
    return -1;
×
1088
  }
1089

1090
#if defined(_TD_DARWIN_64) || defined(TD_ASTRA)  // TD_ASTRA_TODO
1091
  if (lseek(pFileIn->fd, (int32_t)(*offset), 0) < 0) {
1092
    terrno = TAOS_SYSTEM_ERROR(ERRNO);
1093
    return -1;
1094
  }
1095
  int64_t writeLen = 0;
1096
  uint8_t buffer[_SEND_FILE_STEP_] = {0};
1097

1098
  for (int64_t len = 0; len < (size - _SEND_FILE_STEP_); len += _SEND_FILE_STEP_) {
1099
    size_t rlen = read(pFileIn->fd, (void *)buffer, _SEND_FILE_STEP_);
1100
    if (rlen <= 0) {
1101
      return writeLen;
1102
    } else if (rlen < _SEND_FILE_STEP_) {
1103
      write(pFileOut->fd, (void *)buffer, (uint32_t)rlen);
1104
      return (int64_t)(writeLen + rlen);
1105
    } else {
1106
      write(pFileOut->fd, (void *)buffer, _SEND_FILE_STEP_);
1107
      writeLen += _SEND_FILE_STEP_;
1108
    }
1109
  }
1110

1111
  int64_t remain = size - writeLen;
1112
  if (remain > 0) {
1113
    size_t rlen = read(pFileIn->fd, (void *)buffer, (size_t)remain);
1114
    if (rlen <= 0) {
1115
      return writeLen;
1116
    } else {
1117
      write(pFileOut->fd, (void *)buffer, (uint32_t)remain);
1118
      writeLen += remain;
1119
    }
1120
  }
1121
  return writeLen;
1122

1123
#else  // for linux
1124

1125
  int64_t leftbytes = size;
28✔
1126
  int64_t sentbytes;
1127

1128
  while (leftbytes > 0) {
56✔
1129
#ifdef _TD_ARM_32
1130
    sentbytes = sendfile(pFileOut->fd, pFileIn->fd, (long int *)offset, leftbytes);
1131
#else
1132
    sentbytes = sendfile(pFileOut->fd, pFileIn->fd, offset, leftbytes);
28✔
1133
#endif
1134
    if (sentbytes == -1) {
28!
1135
      if (ERRNO == EINTR || ERRNO == EAGAIN || ERRNO == EWOULDBLOCK) {
×
1136
        continue;
×
1137
      } else {
1138
        terrno = TAOS_SYSTEM_ERROR(ERRNO);
×
1139
        return -1;
×
1140
      }
1141
    } else if (sentbytes == 0) {
28!
1142
      return (int64_t)(size - leftbytes);
×
1143
    }
1144

1145
    leftbytes -= sentbytes;
28✔
1146
  }
1147

1148
  return size;
28✔
1149
#endif
1150
}
1151

1152
bool lastErrorIsFileNotExist() { return terrno == TAOS_SYSTEM_ERROR(ENOENT); }
34,194✔
1153

1154
#endif  // WINDOWS
1155

1156
TdFilePtr taosOpenFile(const char *path, int32_t tdFileOptions) {
36,536,899✔
1157
  if (path == NULL) {
36,536,899✔
1158
    terrno = TSDB_CODE_INVALID_PARA;
1✔
1159
    return NULL;
1✔
1160
  }
1161
  STUB_RAND_IO_ERR(NULL)
1162
  FILE *fp = NULL;
36,536,898✔
1163
#ifdef WINDOWS
1164
  HANDLE hFile = NULL;
1165
#else
1166
  int fd = -1;
36,536,898✔
1167
#endif
1168
  if (tdFileOptions & TD_FILE_STREAM) {
36,536,898✔
1169
    fp = taosOpenFileForStream(path, tdFileOptions);
17,052,155✔
1170
    if (fp == NULL) return NULL;
17,052,154✔
1171
  } else {
1172
#ifdef WINDOWS
1173
    hFile = taosOpenFileNotStream(path, tdFileOptions);
1174
    if (hFile == INVALID_HANDLE_VALUE) return NULL;
1175
#else
1176
    fd = taosOpenFileNotStream(path, tdFileOptions);
19,484,743✔
1177
    if (fd == -1) return NULL;
19,488,508✔
1178
#endif
1179
  }
1180

1181
  TdFilePtr pFile = (TdFilePtr)taosMemoryMalloc(sizeof(TdFile));
36,489,043✔
1182
  if (pFile == NULL) {
36,489,665!
1183
#ifdef WINDOWS
1184
    if (hFile != NULL) CloseHandle(hFile);
1185
#else
1186
    if (fd >= 0) (void)close(fd);
×
1187
#endif
1188
    if (fp != NULL) (void)fclose(fp);
×
1189
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
1190
    return NULL;
×
1191
  }
1192

1193
#if FILE_WITH_LOCK
1194
  (void)taosThreadRwlockInit(&(pFile->rwlock), NULL);
36,489,665✔
1195
#endif
1196
  pFile->fp = fp;
36,485,349✔
1197

1198
#ifdef WINDOWS
1199
  pFile->hFile = hFile;
1200
  pFile->tdFileOptions = tdFileOptions;
1201
  // do nothing, since the property of pmode is set with _O_TEMPORARY; the OS will recycle
1202
  // the file handle, as well as the space on disk.
1203
#else
1204
  pFile->fd = fd;
36,485,349✔
1205
  // Remove it instantly, so when the program exits normally/abnormally, the file
1206
  // will be automatically remove by OS.
1207
  if (tdFileOptions & TD_FILE_AUTO_DEL) {
36,485,349✔
1208
    if (-1 == unlink(path)) {
9,619✔
1209
      terrno = TAOS_SYSTEM_ERROR(ERRNO);
2,094✔
1210
      (void)close(fd);
×
1211
      taosMemoryFree(pFile);
×
1212
      return NULL;
×
1213
    }
1214
  }
1215
#endif
1216

1217
  return pFile;
36,483,255✔
1218
}
1219

1220
int32_t taosCloseFile(TdFilePtr *ppFile) {
50,154,321✔
1221
  int32_t code = 0;
50,154,321✔
1222
  if (ppFile == NULL || *ppFile == NULL) {
50,154,321!
1223
    return 0;
13,656,987✔
1224
  }
1225
#if FILE_WITH_LOCK
1226
  (void)taosThreadRwlockWrlock(&((*ppFile)->rwlock));
36,497,334✔
1227
#endif
1228
  if ((*ppFile)->fp != NULL) {
36,499,356✔
1229
    TAOS_UNUSED(fflush((*ppFile)->fp));
17,051,365✔
1230
    TAOS_UNUSED(fclose((*ppFile)->fp));
17,051,366✔
1231
    (*ppFile)->fp = NULL;
17,051,364✔
1232
  }
1233
#ifdef WINDOWS
1234
  if ((*ppFile)->hFile != NULL) {
1235
    // FlushFileBuffers((*ppFile)->hFile);
1236
    if (!CloseHandle((*ppFile)->hFile)) {
1237
      terrno = TAOS_SYSTEM_WINAPI_ERROR(GetLastError());
1238
      code = -1;
1239
    }
1240
    (*ppFile)->hFile = NULL;
1241
#else
1242
  if ((*ppFile)->fd >= 0) {
36,499,355✔
1243
    // warning: never fsync silently in base lib
1244
    /*fsync((*ppFile)->fd);*/
1245
    code = close((*ppFile)->fd);
19,447,912✔
1246
    if (-1 == code) {
19,450,742!
1247
      terrno = TAOS_SYSTEM_ERROR(ERRNO);
×
1248
    }
1249
    (*ppFile)->fd = -1;
19,450,957✔
1250
#endif
1251
  }
1252
#if FILE_WITH_LOCK
1253
  (void)taosThreadRwlockUnlock(&((*ppFile)->rwlock));
36,502,400✔
1254
  (void)taosThreadRwlockDestroy(&((*ppFile)->rwlock));
36,502,118✔
1255
#endif
1256
  taosMemoryFree(*ppFile);
36,499,977!
1257
  *ppFile = NULL;
36,500,596✔
1258
  return code;
36,500,596✔
1259
}
1260

1261
int64_t taosPReadFile(TdFilePtr pFile, void *buf, int64_t count, int64_t offset) {
970,784✔
1262
  STUB_RAND_IO_ERR(terrno)
1263
  if (pFile == NULL) {
970,784✔
1264
    terrno = TSDB_CODE_INVALID_PARA;
1✔
1265
    return -1;
1✔
1266
  }
1267

1268
  int32_t code = 0;
970,783✔
1269

1270
#ifdef WINDOWS
1271
#if FILE_WITH_LOCK
1272
  (void)taosThreadRwlockRdlock(&(pFile->rwlock));
1273
#endif
1274

1275
  if (pFile->hFile == NULL) {
1276
#if FILE_WITH_LOCK
1277
    (void)taosThreadRwlockUnlock(&(pFile->rwlock));
1278
#endif
1279

1280
    terrno = TSDB_CODE_INVALID_PARA;
1281
    return -1;
1282
  }
1283

1284
  DWORD      ret = 0;
1285
  OVERLAPPED ol = {0};
1286
  ol.OffsetHigh = (uint32_t)((offset & 0xFFFFFFFF00000000LL) >> 0x20);
1287
  ol.Offset = (uint32_t)(offset & 0xFFFFFFFFLL);
1288

1289
  SetLastError(0);
1290
  BOOL result = ReadFile(pFile->hFile, buf, count, &ret, &ol);
1291
  if (!result && GetLastError() != ERROR_HANDLE_EOF) {
1292
    code = TAOS_SYSTEM_WINAPI_ERROR(GetLastError());
1293
    ret = -1;
1294
  }
1295
#else
1296
#if FILE_WITH_LOCK
1297
  (void)taosThreadRwlockRdlock(&(pFile->rwlock));
970,783✔
1298
#endif
1299

1300
  if (pFile->fd < 0) {
970,890!
1301
#if FILE_WITH_LOCK
1302
    (void)taosThreadRwlockUnlock(&(pFile->rwlock));
×
1303
#endif
1304
    terrno = TSDB_CODE_INVALID_PARA;
×
1305
    return -1;
×
1306
  }
1307
#ifndef TD_ASTRA
1308
  int64_t ret = pread(pFile->fd, buf, count, offset);
970,890✔
1309
  if (-1 == ret) {
970,827!
1310
    code = TAOS_SYSTEM_ERROR(ERRNO);
×
1311
  }
1312
#else  // TD_ASTRA_TODO
1313
  int64_t ret = -1;
1314
  int64_t cur = lseek(pFile->fd, 0, SEEK_CUR);
1315
  if (cur < 0) {
1316
    code = TAOS_SYSTEM_ERROR(ERRNO);
1317
    goto _exit;
1318
  }
1319
  if (lseek(pFile->fd, offset, SEEK_SET) < 0) {
1320
    code = TAOS_SYSTEM_ERROR(ERRNO);
1321
    goto _exit;
1322
  }
1323
  if ((ret = read(pFile->fd, buf, count)) < 0) {
1324
    code = TAOS_SYSTEM_ERROR(ERRNO);
1325
    goto _exit;
1326
  }
1327
_exit:
1328
  if (cur >= 0 && lseek(pFile->fd, cur, SEEK_SET) < 0) {
1329
    code = TAOS_SYSTEM_ERROR(ERRNO);
1330
  }
1331
#endif
1332
#endif
1333
#if FILE_WITH_LOCK
1334
  (void)taosThreadRwlockUnlock(&(pFile->rwlock));
970,827✔
1335
#endif
1336

1337
  if (code) {
970,871!
1338
    terrno = code;
×
1339
    return -1;
×
1340
  }
1341

1342
  return ret;
970,908✔
1343
}
1344

1345
int32_t taosFsyncFile(TdFilePtr pFile) {
2,274,748✔
1346
  if (pFile == NULL) {
2,274,748✔
1347
    return 0;
2,429✔
1348
  }
1349

1350
  int32_t code = 0;
2,272,319✔
1351
  // this implementation is WRONG
1352
  // fflush is not a replacement of fsync
1353
  if (pFile->fp != NULL) {
2,272,319✔
1354
    code = fflush(pFile->fp);
473,983✔
1355
    if (0 != code) {
473,983!
1356
      terrno = TAOS_SYSTEM_ERROR(ERRNO);
×
1357
      return terrno;
×
1358
    }
1359

1360
    return 0;
473,983✔
1361
  }
1362

1363
#ifdef WINDOWS
1364
  if (pFile->hFile != NULL) {
1365
    if (pFile->tdFileOptions & TD_FILE_WRITE_THROUGH) {
1366
      return 0;
1367
    }
1368
    bool ret = FlushFileBuffers(pFile->hFile);
1369
    if (!ret) {
1370
      terrno = TAOS_SYSTEM_WINAPI_ERROR(GetLastError());
1371
      return terrno;
1372
    }
1373
    return 0;
1374
  }
1375
#else
1376
  if (pFile->fd >= 0) {
1,798,336!
1377
    code = fsync(pFile->fd);
1,798,414✔
1378
    if (-1 == code) {
1,798,943!
1379
#ifndef TD_ASTRA
1380
      terrno = TAOS_SYSTEM_ERROR(ERRNO);
×
1381
#else
1382
      terrno = 0;  // TD_ASTRA_TODO
1383
#endif
1384
      return terrno;
×
1385
    }
1386
  }
1387
#endif
1388

1389
  return 0;
1,798,977✔
1390
}
1391

1392
void taosFprintfFile(TdFilePtr pFile, const char *format, ...) {
198,500,796✔
1393
  if (pFile == NULL || pFile->fp == NULL) {
198,500,796!
1394
    return;
62,241,200✔
1395
  }
1396
  va_list ap;
1397
  va_start(ap, format);
136,259,596✔
1398
  (void)vfprintf(pFile->fp, format, ap);
136,259,596✔
1399
  va_end(ap);
136,333,596✔
1400
}
1401

1402
bool taosValidFile(TdFilePtr pFile) {
3✔
1403
#ifdef WINDOWS
1404
  return pFile != NULL && pFile->hFile != NULL;
1405
#else
1406
  return pFile != NULL && pFile->fd > 0;
3!
1407
#endif
1408
}
1409

1410
int32_t taosUmaskFile(int32_t maskVal) {
45,112✔
1411
#ifdef WINDOWS
1412
  return 0;
1413
#else
1414
  return umask(maskVal);
45,112✔
1415
#endif
1416
}
1417

1418
int64_t taosGetLineFile(TdFilePtr pFile, char **__restrict ptrBuf) {
769,688✔
1419
  int64_t ret = -1;
769,688✔
1420
  int32_t code = 0;
769,688✔
1421

1422
  if (pFile == NULL || ptrBuf == NULL) {
769,688✔
1423
    terrno = TSDB_CODE_INVALID_PARA;
3✔
1424
    goto END;
3✔
1425
  }
1426
  if (*ptrBuf != NULL) {
769,685✔
1427
    taosMemoryFreeClear(*ptrBuf);
769,580!
1428
  }
1429

1430
  if (pFile->fp == NULL) {
769,685!
1431
    terrno = TSDB_CODE_INVALID_PARA;
×
1432
    goto END;
×
1433
  }
1434

1435
#if FILE_WITH_LOCK
1436
  (void)taosThreadRwlockRdlock(&(pFile->rwlock));
769,685✔
1437
#endif
1438

1439
#ifdef WINDOWS
1440
  size_t bufferSize = 512;
1441
  *ptrBuf = taosMemoryMalloc(bufferSize);
1442
  if (*ptrBuf == NULL) {
1443
    goto END;
1444
  }
1445

1446
  size_t bytesRead = 0;
1447
  size_t totalBytesRead = 0;
1448

1449
  while (1) {
1450
    char *result = fgets(*ptrBuf + totalBytesRead, bufferSize - totalBytesRead, pFile->fp);
1451
    if (result == NULL) {
1452
      if (feof(pFile->fp)) {
1453
        break;
1454
      } else {
1455
        ret = -1;
1456
        terrno = TAOS_SYSTEM_ERROR(ferror(pFile->fp));
1457
        taosMemoryFreeClear(*ptrBuf);
1458
        goto END;
1459
      }
1460
    }
1461
    bytesRead = strlen(*ptrBuf + totalBytesRead);
1462
    totalBytesRead += bytesRead;
1463

1464
    if (totalBytesRead < bufferSize - 1 || (*ptrBuf)[totalBytesRead - 1] == '\n') {
1465
      break;
1466
    }
1467

1468
    bufferSize += 512;
1469
    void *newBuf = taosMemoryRealloc(*ptrBuf, bufferSize);
1470
    if (newBuf == NULL) {
1471
      taosMemoryFreeClear(*ptrBuf);
1472
      goto END;
1473
    }
1474

1475
    *ptrBuf = newBuf;
1476
  }
1477

1478
  (*ptrBuf)[totalBytesRead] = '\0';
1479
  ret = (totalBytesRead > 0 ? totalBytesRead : -1); // -1 means EOF
1480
#elif defined(TD_ASTRA)
1481
  size_t bufsize = 128;
1482
  if (*ptrBuf == NULL) {
1483
    *ptrBuf = (char *)taosMemoryMalloc(bufsize);
1484
    if (*ptrBuf == NULL) {
1485
      goto END;
1486
    }
1487
  }
1488
  size_t pos = 0;
1489
  int    c;
1490
  while ((c = fgetc(pFile->fp)) != EOF) {
1491
    if (pos + 1 >= bufsize) {
1492
      size_t new_size = bufsize << 1;
1493
      char  *new_line = (char *)taosMemoryRealloc(*ptrBuf, new_size);
1494
      if (new_line == NULL) {
1495
        goto END;
1496
      }
1497
      *ptrBuf = new_line;
1498
      bufsize = new_size;
1499
    }
1500
    (*ptrBuf)[pos++] = (char)c;
1501
    if (c == '\n') {
1502
      break;
1503
    }
1504
  }
1505
  if (pos == 0 && c == EOF) {
1506
    goto END;
1507
  }
1508
  (*ptrBuf)[pos] = '\0';
1509
  ret = pos;
1510
#else
1511
  size_t len = 0;
769,685✔
1512
  ret = getline(ptrBuf, &len, pFile->fp);
769,685✔
1513
  if (-1 == ret) {
769,685✔
1514
    terrno = TAOS_SYSTEM_ERROR(ERRNO);
105✔
1515
  }
1516
#endif
1517

1518
END:
769,580✔
1519

1520
#if FILE_WITH_LOCK
1521
  (void)taosThreadRwlockUnlock(&(pFile->rwlock));
769,688✔
1522
#endif
1523

1524
  return ret;
769,688✔
1525
}
1526

1527
int64_t taosGetsFile(TdFilePtr pFile, int32_t maxSize, char *__restrict buf) {
173,326,933✔
1528
  if (pFile == NULL || buf == NULL) {
173,326,933✔
1529
    terrno = TSDB_CODE_INVALID_PARA;
3✔
1530
    return terrno;
3✔
1531
  }
1532

1533
  if (pFile->fp == NULL) {
173,326,930!
1534
    terrno = TSDB_CODE_INVALID_PARA;
×
1535
    return terrno;
×
1536
  }
1537

1538
  if (fgets(buf, maxSize, pFile->fp) == NULL) {
173,326,930✔
1539
    if (feof(pFile->fp)) {
62,086!
1540
      return 0;
62,086✔
1541
    } else {
1542
      terrno = TAOS_SYSTEM_ERROR(ferror(pFile->fp));
×
1543
      return terrno;
×
1544
    }
1545
  }
1546

1547
  return strlen(buf);
173,264,844✔
1548
}
1549

1550
int32_t taosEOFFile(TdFilePtr pFile) {
56,695,750✔
1551
  if (pFile == NULL) {
56,695,750✔
1552
    terrno = TSDB_CODE_INVALID_PARA;
2✔
1553
    return -1;
2✔
1554
  }
1555
  if (pFile->fp == NULL) {
56,695,748!
1556
    terrno = TSDB_CODE_INVALID_PARA;
×
1557
    return -1;
×
1558
  }
1559

1560
  return feof(pFile->fp);
56,695,748✔
1561
}
1562

1563
bool taosCheckAccessFile(const char *pathname, int32_t tdFileAccessOptions) {
865,540✔
1564
  if (pathname == NULL) {
865,540✔
1565
    terrno = TSDB_CODE_INVALID_PARA;
1✔
1566
    return false;  // invalid parameter
1✔
1567
  }
1568
  int flags = 0;
865,539✔
1569

1570
  if (tdFileAccessOptions & TD_FILE_ACCESS_EXIST_OK) {
865,539!
1571
    flags |= F_OK;
865,622✔
1572
  }
1573

1574
  if (tdFileAccessOptions & TD_FILE_ACCESS_READ_OK) {
865,539✔
1575
    flags |= R_OK;
46,308✔
1576
  }
1577

1578
  if (tdFileAccessOptions & TD_FILE_ACCESS_WRITE_OK) {
865,539✔
1579
    flags |= W_OK;
46,308✔
1580
  }
1581

1582
  if (tdFileAccessOptions & TD_FILE_ACCESS_EXEC_OK) {
865,539!
1583
    flags |= X_OK;
×
1584
  }
1585
#ifdef WINDOWS
1586
  return _access(pathname, flags) == 0;
1587
#else
1588
  return access(pathname, flags) == 0;
865,539✔
1589
#endif
1590
}
1591

1592
bool taosCheckExistFile(const char *pathname) { return taosCheckAccessFile(pathname, TD_FILE_ACCESS_EXIST_OK); };
819,229✔
1593

1594
int32_t taosCompressFile(char *srcFileName, char *destFileName) {
5✔
1595
  OS_PARAM_CHECK(srcFileName);
5✔
1596
  OS_PARAM_CHECK(destFileName);
4✔
1597
  int32_t   compressSize = 163840;
3✔
1598
  int32_t   ret = 0;
3✔
1599
  int32_t   len = 0;
3✔
1600
  gzFile    dstFp = NULL;
3✔
1601
  TdFilePtr pSrcFile = NULL;
3✔
1602

1603
  char *data = taosMemoryMalloc(compressSize);
3!
1604
  if (NULL == data) {
3!
1605
    return terrno;
×
1606
  }
1607

1608
  pSrcFile = taosOpenFile(srcFileName, TD_FILE_READ | TD_FILE_STREAM);
3✔
1609
  if (pSrcFile == NULL) {
3✔
1610
    ret = terrno;
1✔
1611
    goto cmp_end;
1✔
1612
  }
1613

1614
  int access = O_BINARY | O_WRONLY | O_TRUNC | O_CREAT;
2✔
1615
#ifdef WINDOWS
1616
  int32_t pmode = _S_IREAD | _S_IWRITE;
1617
#else
1618
  int32_t pmode = S_IRWXU | S_IRWXG | S_IRWXO;
2✔
1619
#endif
1620
  int fd = open(destFileName, access, pmode);
2✔
1621
  if (-1 == fd) {
2✔
1622
    terrno = TAOS_SYSTEM_ERROR(ERRNO);
1✔
1623
    ret = terrno;
1✔
1624
    goto cmp_end;
1✔
1625
  }
1626

1627
  // Both gzclose() and fclose() will close the associated fd, so they need to have different fds.
1628
  FileFd gzFd = dup(fd);
1✔
1629
  if (-1 == gzFd) {
1!
1630
    terrno = TAOS_SYSTEM_ERROR(ERRNO);
×
1631
    ret = terrno;
×
1632
    goto cmp_end;
×
1633
  }
1634
  dstFp = gzdopen(gzFd, "wb6f");
1✔
1635
  if (dstFp == NULL) {
1!
1636
    terrno = TAOS_SYSTEM_ERROR(ERRNO);
×
1637
    ret = terrno;
×
1638
    (void)close(gzFd);
×
1639
    goto cmp_end;
×
1640
  }
1641

1642
  while (!feof(pSrcFile->fp)) {
2✔
1643
    len = (int32_t)fread(data, 1, compressSize, pSrcFile->fp);
1✔
1644
    if (len > 0) {
1!
1645
      if (gzwrite(dstFp, data, len) == 0) {
1!
1646
        terrno = TAOS_SYSTEM_ERROR(ERRNO);
×
1647
        ret = terrno;
×
1648
        goto cmp_end;
×
1649
      }
1650
    }
1651
  }
1652

1653
cmp_end:
1✔
1654

1655
  if (fd >= 0) {
3✔
1656
    TAOS_SKIP_ERROR(close(fd));
2✔
1657
  }
1658
  if (pSrcFile) {
3✔
1659
    TAOS_SKIP_ERROR(taosCloseFile(&pSrcFile));
2✔
1660
  }
1661

1662
  if (dstFp) {
3✔
1663
    TAOS_SKIP_ERROR(gzclose(dstFp));
1✔
1664
  }
1665

1666
  taosMemoryFree(data);
3!
1667

1668
  return ret;
3✔
1669
}
1670

1671
int32_t taosSetFileHandlesLimit() {
24,379✔
1672
#ifdef WINDOWS
1673
  const int max_handles = 8192;
1674
  int       res = _setmaxstdio(max_handles);
1675
  return res == max_handles ? 0 : -1;
1676
#endif
1677
  return 0;
24,379✔
1678
}
1679

1680
int32_t taosLinkFile(char *src, char *dst) {
653✔
1681
#ifndef WINDOWS
1682
  if (-1 == link(src, dst)) {
653✔
1683
    terrno = TAOS_SYSTEM_ERROR(ERRNO);
1✔
1684
    return terrno;
1✔
1685
  }
1686
#endif
1687
  return 0;
652✔
1688
}
1689

1690
FILE *taosOpenCFile(const char *filename, const char *mode) {
707,246✔
1691
  if (filename == NULL || mode == NULL) {
707,246!
1692
    terrno = TSDB_CODE_INVALID_PARA;
×
1693
    return NULL;
2✔
1694
  }
1695
  STUB_RAND_IO_ERR(NULL)
1696
  FILE *f = fopen(filename, mode);
708,503✔
1697
  if (NULL == f) {
709,207✔
1698
    terrno = TAOS_SYSTEM_ERROR(ERRNO);
1✔
1699
  }
1700
  return f;
709,207✔
1701
}
1702

1703
int taosSeekCFile(FILE *file, int64_t offset, int whence) {
406,320✔
1704
  if (NULL == file) {
406,320✔
1705
    terrno = TSDB_CODE_INVALID_PARA;
1✔
1706
    return terrno;
1✔
1707
  }
1708
#ifdef WINDOWS
1709
  return _fseeki64(file, offset, whence);
1710
#else
1711
  int     code = fseeko(file, offset, whence);
406,319✔
1712
  if (-1 == code) {
406,326!
1713
    terrno = TAOS_SYSTEM_ERROR(ERRNO);
×
1714
    code = terrno;
×
1715
  }
1716
  return code;
406,330✔
1717
#endif
1718
}
1719

1720
size_t taosReadFromCFile(void *buffer, size_t size, size_t count, FILE *stream) {
406,319✔
1721
  if (buffer == NULL || stream == NULL) {
406,319!
1722
    terrno = TSDB_CODE_INVALID_PARA;
×
1723
    return 0;
2✔
1724
  }
1725
  STUB_RAND_IO_ERR(terrno)
1726
  return fread(buffer, size, count, stream);
406,327✔
1727
}
1728

1729
#if 0
1730
size_t taosWriteToCFile(const void *ptr, size_t size, size_t nitems, FILE *stream) {
1731
  STUB_RAND_IO_ERR(terrno)
1732
  return fwrite(ptr, size, nitems, stream);
1733
}
1734
#endif
1735

1736
int taosCloseCFile(FILE *f) { return fclose(f); }
709,159✔
1737

1738
int taosSetAutoDelFile(char *path) {
709,206✔
1739
#ifdef WINDOWS
1740
  bool succ = SetFileAttributes(path, FILE_ATTRIBUTE_TEMPORARY);
1741
  if (succ) {
1742
    return 0;
1743
  } else {
1744
    terrno = TAOS_SYSTEM_WINAPI_ERROR(GetLastError());
1745
    return terrno;
1746
  }
1747
#else
1748
  if (-1 == unlink(path)) {
709,206!
1749
    terrno = TAOS_SYSTEM_ERROR(ERRNO);
×
1750
    return terrno;
×
1751
  }
1752
  return 0;
709,206✔
1753
#endif
1754
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc