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

taosdata / TDengine / #3660

15 Mar 2025 09:06AM UTC coverage: 62.039% (-1.3%) from 63.314%
#3660

push

travis-ci

web-flow
feat(stream): support stream processing for virtual tables (#30144)

* enh: add client processing

* enh: add mnode vtables processing

* enh: add mnode vtable processing

* enh: add normal child vtable support

* fix: compile issues

* fix: compile issues

* fix: create stream issues

* fix: multi stream scan issue

* fix: remove debug info

* fix: agg task and task level issues

* fix: correct task output type

* fix: split vtablescan from agg

* fix: memory leak issues

* fix: add limitations

* Update 09-error-code.md

* Update 09-error-code.md

* fix: remove usless case

* feat(stream): extract original table data in source scan task

Implemented functionality in the source task to extract data
corresponding to the virtual table from the original table using WAL.
The extracted data is then sent to the downstream merge task for further
processing.

* feat(stream): multi-way merge using loser tree in virtual merge task

Implemented multi-way merge in the merge task using a loser tree to
combine data from multiple original table into a single virtual table.
The merged virtual table data is then pushed downstream for further
processing.  Introduced memory limit handling during the merge process
with configurable behavior when the memory limit is reached.

* fix(test): remove useless cases

---------

Co-authored-by: dapan1121 <wpan@taosdata.com>
Co-authored-by: Pan Wei <72057773+dapan1121@users.noreply.github.com>

154078 of 317582 branches covered (48.52%)

Branch coverage included in aggregate %.

313 of 2391 new or added lines in 34 files covered. (13.09%)

26134 existing lines in 205 files now uncovered.

240261 of 318051 relevant lines covered (75.54%)

16655189.27 hits per line

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

77.38
/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
  int            refId;
56
  HANDLE         hFile;
57
  FILE          *fp;
58
  int32_t        tdFileOptions;
59
} TdFile;
60
#else
61
typedef struct TdFile {
62
  TdThreadRwlock rwlock;
63
  int            refId;
64
  FileFd         fd;
65
  FILE          *fp;
66
} TdFile;
67
#endif  // WINDOWS
68

69
#define FILE_WITH_LOCK 1
70

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

85
void taosGetTmpfilePath(const char *inputTmpDir, const char *fileNamePrefix, char *dstPath) {
678,188✔
86
  if (inputTmpDir == NULL || fileNamePrefix == NULL) return;
678,188!
87
#ifdef WINDOWS
88

89
  char tmpPath[PATH_MAX];
90

91
  int32_t len = (int32_t)strlen(inputTmpDir);
92
  memcpy(tmpPath, inputTmpDir, len);
93

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

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

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

104
#else
105

106
  char    tmpPath[PATH_MAX];
107
  int32_t len = strlen(inputTmpDir);
678,562✔
108
  (void)memcpy(tmpPath, inputTmpDir, len);
678,562✔
109
  static uint64_t seqId = 0;
110

111
  if (tmpPath[len - 1] != '/') {
678,562✔
112
    tmpPath[len++] = '/';
1✔
113
  }
114

115
  snprintf(tmpPath + len, sizeof(tmpPath) - len, "%s%s%s", TD_TMP_FILE_PREFIX, fileNamePrefix, "-%d-%s");
678,562✔
116

117
  char rand[32] = {0};
678,562✔
118

119
  (void)snprintf(rand, sizeof(rand), "%" PRIu64, atomic_add_fetch_64(&seqId, 1));
678,562✔
120

121
  (void)snprintf(dstPath, PATH_MAX, tmpPath, taosGetPId(), rand);
679,084✔
122

123
#endif
124
}
125

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

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

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

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

165
    if (bytes == 0) break;
131!
166

167
    size += bytes;
131✔
168

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

176
  code = taosFsyncFile(pFileTo);
121✔
177
  if (code != 0) {
121!
178
    goto _err;
×
179
  }
180

181
  TAOS_UNUSED(taosCloseFile(&pFileFrom));
121✔
182
  TAOS_UNUSED(taosCloseFile(&pFileTo));
121✔
183

184
  if (code != 0) {
121!
185
    terrno = code;
×
186
    return -1;
×
187
  }
188

189
  return size;
121✔
190

191
_err:
2✔
192

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

198
  terrno = code;
2✔
199
  return -1;
2✔
200
#endif
201
}
202

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

224
  return fp;
16✔
225
}
226

227
int32_t taosRemoveFile(const char *path) {
977,995✔
228
  OS_PARAM_CHECK(path);
977,995✔
229
  int32_t code = remove(path);
977,994✔
230
  if (-1 == code) {
978,016✔
231
    terrno = TAOS_SYSTEM_ERROR(ERRNO);
679,103✔
232
    return terrno;
679,110✔
233
  }
234
  return code;
298,913✔
235
}
236

237
int32_t taosRenameFile(const char *oldName, const char *newName) {
251,401✔
238
  OS_PARAM_CHECK(oldName);
251,401✔
239
  OS_PARAM_CHECK(newName);
251,400✔
240
#ifdef WINDOWS
241
  bool finished = false;
242

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

250
  BOOL result = MoveFileTransacted(oldName, newName, NULL, NULL, MOVEFILE_REPLACE_EXISTING, transactionHandle);
251

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

265
  CloseHandle(transactionHandle);
266

267
  return finished ? 0 : terrno;
268
#else
269
#ifdef TD_ASTRA // TD_ASTRA_TODO
270
  if (taosCheckExistFile(newName)) taosRemoveFile(newName);
271
#endif
272
  int32_t code = rename(oldName, newName);
251,399✔
273
  if (-1 == code) {
251,389✔
274
    terrno = TAOS_SYSTEM_ERROR(ERRNO);
316✔
275
    return terrno;
313✔
276
  }
277

278
  return TSDB_CODE_SUCCESS;
251,073✔
279
#endif
280
}
281

282
int32_t taosStatFile(const char *path, int64_t *size, int64_t *mtime, int64_t *atime) {
475,345✔
283
  OS_PARAM_CHECK(path);
475,345✔
284
#ifdef WINDOWS
285
  struct _stati64 fileStat;
286
  int32_t         code = _stati64(path, &fileStat);
287
#else
288
  struct stat fileStat;
289
  int32_t     code = stat(path, &fileStat);
475,344✔
290
#endif
291
  if (-1 == code) {
475,317✔
292
    terrno = TAOS_SYSTEM_ERROR(ERRNO);
65,054✔
293
    return terrno;
65,116✔
294
  }
295

296
  if (size != NULL) {
410,263✔
297
    *size = fileStat.st_size;
382,485✔
298
  }
299

300
  if (mtime != NULL) {
410,263✔
301
    *mtime = fileStat.st_mtime;
15,337✔
302
  }
303

304
  if (atime != NULL) {
410,263!
305
    *atime = fileStat.st_atime;
×
306
  }
307

308
  return 0;
410,263✔
309
}
310

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

325
  if (diskid != NULL) {
2,068✔
326
    *diskid = fileStat.st_dev;
2,067✔
327
  }
328

329
  return 0;
2,068✔
330
}
331

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

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

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

353
#else
354
  if (pFile == NULL || pFile->fd < 0) {
35,697!
355
    terrno = TSDB_CODE_INVALID_PARA;
×
356
    return terrno;
1✔
357
  }
358

359
  struct stat fileStat;
360
  int32_t     code = fstat(pFile->fd, &fileStat);
35,733✔
361
  if (-1 == code) {
35,726!
362
    terrno = TAOS_SYSTEM_ERROR(ERRNO);
×
363
    return terrno;
×
364
  }
365

366
  if (stDev != NULL) {
35,749✔
367
    *stDev = fileStat.st_dev;
35,739✔
368
  }
369

370
  if (stIno != NULL) {
35,749!
371
    *stIno = fileStat.st_ino;
35,754✔
372
  }
373
#endif
374

375
  return 0;
35,749✔
376
}
377

378
FILE *taosOpenFileForStream(const char *path, int32_t tdFileOptions) {
12,581,475✔
379
  if (path == NULL) {
12,581,475✔
380
    terrno = TSDB_CODE_INVALID_PARA;
1✔
381
    return NULL;
1✔
382
  }
383
  char *mode = NULL;
12,581,474✔
384
  if (tdFileOptions & TD_FILE_APPEND) {
12,581,474✔
385
    mode = (tdFileOptions & TD_FILE_TEXT) ? "at+" : "ab+";
13,543!
386
  } else if (tdFileOptions & TD_FILE_TRUNC) {
12,567,931✔
387
    mode = (tdFileOptions & TD_FILE_TEXT) ? "wt+" : "wb+";
12,111✔
388
  } else if ((tdFileOptions & TD_FILE_READ) && !(tdFileOptions & TD_FILE_WRITE)) {
12,555,820!
389
    mode = (tdFileOptions & TD_FILE_TEXT) ? "rt" : "rb";
12,555,821!
390
  } else {
391
    mode = (tdFileOptions & TD_FILE_TEXT) ? "rt+" : "rb+";
×
392
  }
393
  if (tdFileOptions & TD_FILE_EXCL) {
12,581,474!
394
    terrno = TSDB_CODE_INVALID_PARA;
×
395
    return NULL;
×
396
  }
397
  FILE *f = fopen(path, mode);
12,581,474✔
398
  if (NULL == f) {
12,581,475✔
399
    terrno = TAOS_SYSTEM_ERROR(ERRNO);
32✔
400
  }
401
  return f;
12,581,475✔
402
}
403

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

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

431
  shareMode |= FILE_SHARE_WRITE;
432

433
  access |= GENERIC_READ;
434

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

613
  BOOL          fSuccess = FALSE;
614
  LARGE_INTEGER fileSize;
615
  OVERLAPPED    overlapped = {0};
616

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

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

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

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

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

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

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

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

707
  LARGE_INTEGER fileOffset;
708
  fileOffset.QuadPart = *offset;
709

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

715
  int64_t writeLen = 0;
716
  uint8_t buffer[_SEND_FILE_STEP_] = {0};
717

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

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

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

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

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

773
#else
774
int taosOpenFileNotStream(const char *path, int32_t tdFileOptions) {
16,198,573✔
775
  if (path == NULL) {
16,198,573!
776
    terrno = TSDB_CODE_INVALID_PARA;
×
777
    return -1;
×
778
  }
779
  int access = O_BINARY;
16,198,573✔
780
  access |= (tdFileOptions & TD_FILE_CREATE) ? O_CREAT : 0;
16,198,573✔
781
  if ((tdFileOptions & TD_FILE_WRITE) && (tdFileOptions & TD_FILE_READ)) {
16,198,573✔
782
    access |= O_RDWR;
864,197✔
783
  } else if (tdFileOptions & TD_FILE_WRITE) {
15,334,376✔
784
    access |= O_WRONLY;
340,341✔
785
  } else if (tdFileOptions & TD_FILE_READ) {
14,994,035!
786
    access |= O_RDONLY;
14,994,198✔
787
  }
788
  access |= (tdFileOptions & TD_FILE_TRUNC) ? O_TRUNC : 0;
16,198,573✔
789
  access |= (tdFileOptions & TD_FILE_APPEND) ? O_APPEND : 0;
16,198,573✔
790
  access |= (tdFileOptions & TD_FILE_TEXT) ? O_TEXT : 0;
16,198,573✔
791
  access |= (tdFileOptions & TD_FILE_EXCL) ? O_EXCL : 0;
16,198,573✔
792
  access |= (tdFileOptions & TD_FILE_CLOEXEC) ? O_CLOEXEC : 0;
16,198,573✔
793

794
  int fd = open(path, access, S_IRWXU | S_IRWXG | S_IRWXO);
16,198,573✔
795
  if (-1 == fd) {
16,203,566✔
796
    terrno = TAOS_SYSTEM_ERROR(ERRNO);
51,688✔
797
  }
798
  return fd;
16,202,716✔
799
}
800

801
int64_t taosReadFile(TdFilePtr pFile, void *buf, int64_t count) {
38,460,272✔
802
  if (pFile == NULL || buf == NULL) {
38,460,272!
803
    terrno = TSDB_CODE_INVALID_PARA;
×
804
    return -1;
2✔
805
  }
806
  STUB_RAND_IO_ERR(terrno)
807
#if FILE_WITH_LOCK
808
  (void)taosThreadRwlockRdlock(&(pFile->rwlock));
38,463,049✔
809
#endif
810

811
  if (pFile->fd < 0) {
38,471,931✔
812
#if FILE_WITH_LOCK
813
    (void)taosThreadRwlockUnlock(&(pFile->rwlock));
852✔
814
#endif
815
    terrno = TSDB_CODE_INVALID_PARA;
×
816
    return -1;
×
817
  }
818

819
  int64_t leftbytes = count;
38,471,079✔
820
  int64_t readbytes;
821
  char   *tbuf = (char *)buf;
38,471,079✔
822
  int32_t code = 0;
38,471,079✔
823

824
  while (leftbytes > 0) {
76,935,585✔
825
#ifdef WINDOWS
826
    readbytes = _read(pFile->fd, (void *)tbuf, (uint32_t)leftbytes);
827
#else
828
    readbytes = read(pFile->fd, (void *)tbuf, (uint32_t)leftbytes);
38,468,399✔
829
#endif
830
    if (readbytes < 0) {
38,468,714✔
831
      if (ERRNO == EINTR) {
109!
832
        continue;
×
833
      } else {
834
        code = TAOS_SYSTEM_ERROR(ERRNO);
109✔
835
#if FILE_WITH_LOCK
836
        (void)taosThreadRwlockUnlock(&(pFile->rwlock));
109✔
837
#endif
838
        terrno = code;
109✔
839
        return -1;
109✔
840
      }
841
    } else if (readbytes == 0) {
38,468,605✔
842
#if FILE_WITH_LOCK
843
      (void)taosThreadRwlockUnlock(&(pFile->rwlock));
4,099✔
844
#endif
845
      return (int64_t)(count - leftbytes);
4,099✔
846
    }
847

848
    leftbytes -= readbytes;
38,464,506✔
849
    tbuf += readbytes;
38,464,506✔
850
  }
851

852
#if FILE_WITH_LOCK
853
  (void)taosThreadRwlockUnlock(&(pFile->rwlock));
38,467,186✔
854
#endif
855

856
  return count;
38,470,704✔
857
}
858

859
int64_t taosWriteFile(TdFilePtr pFile, const void *buf, int64_t count) {
891,086,909✔
860
  STUB_RAND_IO_ERR(terrno)
861
  if (pFile == NULL || buf == NULL) {
891,086,909!
862
    terrno = TSDB_CODE_INVALID_PARA;
×
863
    return 0;
2✔
864
  }
865
#if FILE_WITH_LOCK
866
  (void)taosThreadRwlockWrlock(&(pFile->rwlock));
891,127,945✔
867
#endif
868
  if (pFile->fd < 0) {
891,428,669✔
869
#if FILE_WITH_LOCK
870
    (void)taosThreadRwlockUnlock(&(pFile->rwlock));
12✔
871
#endif
872
    terrno = TSDB_CODE_INVALID_PARA;
×
873
    return 0;
×
874
  }
875

876
  int64_t nleft = count;
891,428,657✔
877
  int64_t nwritten = 0;
891,428,657✔
878
  char   *tbuf = (char *)buf;
891,428,657✔
879
  int32_t code = 0;
891,428,657✔
880

881
  while (nleft > 0) {
1,782,853,615✔
882
    nwritten = write(pFile->fd, (void *)tbuf, (uint32_t)nleft);
891,427,451✔
883
    if (nwritten < 0) {
891,424,959✔
884
      if (ERRNO == EINTR) {
1!
885
        continue;
×
886
      }
887
      code = TAOS_SYSTEM_ERROR(ERRNO);
1✔
888
#if FILE_WITH_LOCK
889
      (void)taosThreadRwlockUnlock(&(pFile->rwlock));
1✔
890
#endif
891
      terrno = code;
1✔
892
      return -1;
1✔
893
    }
894
    nleft -= nwritten;
891,424,958✔
895
    tbuf += nwritten;
891,424,958✔
896
  }
897

898
#if FILE_WITH_LOCK
899
  (void)taosThreadRwlockUnlock(&(pFile->rwlock));
891,426,164✔
900
#endif
901

902
  return count;
891,362,897✔
903
}
904

905
int64_t taosPWriteFile(TdFilePtr pFile, const void *buf, int64_t count, int64_t offset) {
669,854✔
906
  STUB_RAND_IO_ERR(terrno)
907
  if (pFile == NULL || buf == NULL) {
669,854!
908
    terrno = TSDB_CODE_INVALID_PARA;
×
909
    return 0;
2✔
910
  }
911

912
  int32_t code = 0;
669,877✔
913
#if FILE_WITH_LOCK
914
  (void)taosThreadRwlockWrlock(&(pFile->rwlock));
669,877✔
915
#endif
916

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

952
  if (code) {
670,087!
953
    terrno = code;
×
954
  }
955

956
  return ret;
670,135✔
957
}
958

959
int64_t taosLSeekFile(TdFilePtr pFile, int64_t offset, int32_t whence) {
49,216,896✔
960
  if (pFile == NULL || pFile->fd < 0) {
49,216,896!
961
    terrno = TSDB_CODE_INVALID_PARA;
×
962
    return -1;
1✔
963
  }
964
#if FILE_WITH_LOCK
965
  (void)taosThreadRwlockRdlock(&(pFile->rwlock));
49,221,298✔
966
#endif
967

968
  int32_t code = 0;
49,228,479✔
969

970
  int64_t ret = lseek(pFile->fd, offset, whence);
49,228,479✔
971
  if (-1 == ret) {
49,227,223!
972
    code = TAOS_SYSTEM_ERROR(ERRNO);
×
973
  }
974

975
#if FILE_WITH_LOCK
976
  (void)taosThreadRwlockUnlock(&(pFile->rwlock));
49,227,223✔
977
#endif
978

979
  if (code) {
49,226,898!
980
    terrno = code;
×
981
    return -1;
×
982
  }
983

984
  return ret;
49,227,535✔
985
}
986

987
int32_t taosFStatFile(TdFilePtr pFile, int64_t *size, int64_t *mtime) {
102,556✔
988
  if (pFile == NULL) {
102,556✔
989
    terrno = TSDB_CODE_INVALID_PARA;
2✔
990
    return terrno;
2✔
991
  }
992

993
  if (pFile->fd < 0) {
102,554!
994
    terrno = TSDB_CODE_INVALID_PARA;
×
995
    return terrno;
×
996
  }
997

998
  struct stat fileStat;
999
  int32_t     code = fstat(pFile->fd, &fileStat);
102,554✔
1000
  if (-1 == code) {
102,581!
1001
    terrno = TAOS_SYSTEM_ERROR(ERRNO);
×
1002
    return terrno;
×
1003
  }
1004

1005
  if (size != NULL) {
102,605✔
1006
    *size = fileStat.st_size;
102,594✔
1007
  }
1008

1009
  if (mtime != NULL) {
102,605!
1010
    *mtime = fileStat.st_mtime;
×
1011
  }
1012

1013
  return 0;
102,605✔
1014
}
1015

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

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

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

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

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

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

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

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

1125
#else  // for linux
1126

1127
  int64_t leftbytes = size;
21✔
1128
  int64_t sentbytes;
1129

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

1147
    leftbytes -= sentbytes;
21✔
1148
  }
1149

1150
  return size;
21✔
1151
#endif
1152
}
1153

1154
bool lastErrorIsFileNotExist() { return terrno == TAOS_SYSTEM_ERROR(ENOENT); }
33,916✔
1155

1156
#endif  // WINDOWS
1157

1158
TdFilePtr taosOpenFile(const char *path, int32_t tdFileOptions) {
28,778,890✔
1159
  if (path == NULL) {
28,778,890✔
1160
    terrno = TSDB_CODE_INVALID_PARA;
1✔
1161
    return NULL;
1✔
1162
  }
1163
  STUB_RAND_IO_ERR(NULL)
1164
  FILE *fp = NULL;
28,778,889✔
1165
#ifdef WINDOWS
1166
  HANDLE hFile = NULL;
1167
#else
1168
  int fd = -1;
28,778,889✔
1169
#endif
1170
  if (tdFileOptions & TD_FILE_STREAM) {
28,778,889✔
1171
    fp = taosOpenFileForStream(path, tdFileOptions);
12,581,475✔
1172
    if (fp == NULL) return NULL;
12,581,474✔
1173
  } else {
1174
#ifdef WINDOWS
1175
    hFile = taosOpenFileNotStream(path, tdFileOptions);
1176
    if (hFile == INVALID_HANDLE_VALUE) return NULL;
1177
#else
1178
    fd = taosOpenFileNotStream(path, tdFileOptions);
16,197,414✔
1179
    if (fd == -1) return NULL;
16,202,326✔
1180
#endif
1181
  }
1182

1183
  TdFilePtr pFile = (TdFilePtr)taosMemoryMalloc(sizeof(TdFile));
28,732,930!
1184
  if (pFile == NULL) {
28,733,981!
1185
#ifdef WINDOWS
1186
    if (hFile != NULL) CloseHandle(hFile);
1187
#else
1188
    if (fd >= 0) (void)close(fd);
×
1189
#endif
1190
    if (fp != NULL) (void)fclose(fp);
×
1191
    terrno = TSDB_CODE_OUT_OF_MEMORY;
×
1192
    return NULL;
×
1193
  }
1194

1195
#if FILE_WITH_LOCK
1196
  (void)taosThreadRwlockInit(&(pFile->rwlock), NULL);
28,733,981✔
1197
#endif
1198
  pFile->fp = fp;
28,728,612✔
1199
  pFile->refId = 0;
28,728,612✔
1200

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

1220
  return pFile;
28,728,245✔
1221
}
1222

1223
int32_t taosCloseFile(TdFilePtr *ppFile) {
41,013,473✔
1224
  int32_t code = 0;
41,013,473✔
1225
  if (ppFile == NULL || *ppFile == NULL) {
41,013,473!
1226
    return 0;
12,278,269✔
1227
  }
1228
#if FILE_WITH_LOCK
1229
  (void)taosThreadRwlockWrlock(&((*ppFile)->rwlock));
28,735,204✔
1230
#endif
1231
  if ((*ppFile)->fp != NULL) {
28,736,016✔
1232
    TAOS_UNUSED(fflush((*ppFile)->fp));
12,580,698✔
1233
    TAOS_UNUSED(fclose((*ppFile)->fp));
12,580,698✔
1234
    (*ppFile)->fp = NULL;
12,580,698✔
1235
  }
1236
#ifdef WINDOWS
1237
  if ((*ppFile)->hFile != NULL) {
1238
    // FlushFileBuffers((*ppFile)->hFile);
1239
    if (!CloseHandle((*ppFile)->hFile)) {
1240
      terrno = TAOS_SYSTEM_WINAPI_ERROR(GetLastError());
1241
      code = -1;
1242
    }
1243
    (*ppFile)->hFile = NULL;
1244
#else
1245
  if ((*ppFile)->fd >= 0) {
28,736,016✔
1246
    // warning: never fsync silently in base lib
1247
    /*fsync((*ppFile)->fd);*/
1248
    code = close((*ppFile)->fd);
16,155,619✔
1249
    if (-1 == code) {
16,157,064!
1250
      terrno = TAOS_SYSTEM_ERROR(ERRNO);
×
1251
    }
1252
    (*ppFile)->fd = -1;
16,157,116✔
1253
#endif
1254
  }
1255
  (*ppFile)->refId = 0;
28,737,513✔
1256
#if FILE_WITH_LOCK
1257
  (void)taosThreadRwlockUnlock(&((*ppFile)->rwlock));
28,737,513✔
1258
  (void)taosThreadRwlockDestroy(&((*ppFile)->rwlock));
28,737,673✔
1259
#endif
1260
  taosMemoryFree(*ppFile);
28,737,519!
1261
  *ppFile = NULL;
28,737,307✔
1262
  return code;
28,737,307✔
1263
}
1264

1265
int64_t taosPReadFile(TdFilePtr pFile, void *buf, int64_t count, int64_t offset) {
520,830✔
1266
  STUB_RAND_IO_ERR(terrno)
1267
  if (pFile == NULL) {
520,830✔
1268
    terrno = TSDB_CODE_INVALID_PARA;
1✔
1269
    return -1;
1✔
1270
  }
1271

1272
  int32_t code = 0;
520,829✔
1273

1274
#ifdef WINDOWS
1275
#if FILE_WITH_LOCK
1276
  (void)taosThreadRwlockRdlock(&(pFile->rwlock));
1277
#endif
1278

1279
  if (pFile->hFile == NULL) {
1280
#if FILE_WITH_LOCK
1281
    (void)taosThreadRwlockUnlock(&(pFile->rwlock));
1282
#endif
1283

1284
    terrno = TSDB_CODE_INVALID_PARA;
1285
    return -1;
1286
  }
1287

1288
  DWORD      ret = 0;
1289
  OVERLAPPED ol = {0};
1290
  ol.OffsetHigh = (uint32_t)((offset & 0xFFFFFFFF00000000LL) >> 0x20);
1291
  ol.Offset = (uint32_t)(offset & 0xFFFFFFFFLL);
1292

1293
  SetLastError(0);
1294
  BOOL result = ReadFile(pFile->hFile, buf, count, &ret, &ol);
1295
  if (!result && GetLastError() != ERROR_HANDLE_EOF) {
1296
    code = TAOS_SYSTEM_WINAPI_ERROR(GetLastError());
1297
    ret = -1;
1298
  }
1299
#else
1300
#if FILE_WITH_LOCK
1301
  (void)taosThreadRwlockRdlock(&(pFile->rwlock));
520,829✔
1302
#endif
1303

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

1341
  if (code) {
520,938!
1342
    terrno = code;
×
1343
    return -1;
×
1344
  }
1345

1346
  return ret;
520,983✔
1347
}
1348

1349
int32_t taosFsyncFile(TdFilePtr pFile) {
2,253,038✔
1350
  if (pFile == NULL) {
2,253,038✔
1351
    return 0;
2,343✔
1352
  }
1353

1354
  int32_t code = 0;
2,250,695✔
1355
  // this implementation is WRONG
1356
  // fflush is not a replacement of fsync
1357
  if (pFile->fp != NULL) {
2,250,695✔
1358
    code = fflush(pFile->fp);
477,321✔
1359
    if (0 != code) {
477,321!
1360
      terrno = TAOS_SYSTEM_ERROR(ERRNO);
×
1361
      return terrno;
×
1362
    }
1363

1364
    return 0;
477,321✔
1365
  }
1366

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

1393
  return 0;
1,773,850✔
1394
}
1395

1396
void taosFprintfFile(TdFilePtr pFile, const char *format, ...) {
192,613,412✔
1397
  if (pFile == NULL || pFile->fp == NULL) {
192,613,412!
1398
    return;
61,685,791✔
1399
  }
1400
  va_list ap;
1401
  va_start(ap, format);
130,927,621✔
1402
  (void)vfprintf(pFile->fp, format, ap);
130,927,621✔
1403
  va_end(ap);
130,990,709✔
1404
}
1405

1406
bool taosValidFile(TdFilePtr pFile) {
3✔
1407
#ifdef WINDOWS
1408
  return pFile != NULL && pFile->hFile != NULL;
1409
#else
1410
  return pFile != NULL && pFile->fd > 0;
3!
1411
#endif
1412
}
1413

1414
int32_t taosUmaskFile(int32_t maskVal) {
40,157✔
1415
#ifdef WINDOWS
1416
  return 0;
1417
#else
1418
  return umask(maskVal);
40,157✔
1419
#endif
1420
}
1421

1422
int64_t taosGetLineFile(TdFilePtr pFile, char **__restrict ptrBuf) {
229,322✔
1423
  int64_t ret = -1;
229,322✔
1424
  int32_t code = 0;
229,322✔
1425

1426
  if (pFile == NULL || ptrBuf == NULL) {
229,322✔
1427
    terrno = TSDB_CODE_INVALID_PARA;
3✔
1428
    goto END;
3✔
1429
  }
1430
  if (*ptrBuf != NULL) {
229,319✔
1431
    taosMemoryFreeClear(*ptrBuf);
229,272!
1432
  }
1433

1434
  if (pFile->fp == NULL) {
229,319!
1435
    terrno = TSDB_CODE_INVALID_PARA;
×
1436
    goto END;
×
1437
  }
1438

1439
#if FILE_WITH_LOCK
1440
  (void)taosThreadRwlockRdlock(&(pFile->rwlock));
229,319✔
1441
#endif
1442

1443
#ifdef WINDOWS
1444
  size_t bufferSize = 512;
1445
  *ptrBuf = taosMemoryMalloc(bufferSize);
1446
  if (*ptrBuf == NULL) {
1447
    goto END;
1448
  }
1449

1450
  size_t bytesRead = 0;
1451
  size_t totalBytesRead = 0;
1452

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

1468
    if (totalBytesRead < bufferSize - 1 || (*ptrBuf)[totalBytesRead - 1] == '\n') {
1469
      break;
1470
    }
1471

1472
    bufferSize += 512;
1473
    void *newBuf = taosMemoryRealloc(*ptrBuf, bufferSize);
1474
    if (newBuf == NULL) {
1475
      taosMemoryFreeClear(*ptrBuf);
1476
      goto END;
1477
    }
1478

1479
    *ptrBuf = newBuf;
1480
  }
1481

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

1522
END:
229,272✔
1523

1524
#if FILE_WITH_LOCK
1525
  (void)taosThreadRwlockUnlock(&(pFile->rwlock));
229,322✔
1526
#endif
1527

1528
  return ret;
229,322✔
1529
}
1530

1531
int64_t taosGetsFile(TdFilePtr pFile, int32_t maxSize, char *__restrict buf) {
145,265,610✔
1532
  if (pFile == NULL || buf == NULL) {
145,265,610✔
1533
    terrno = TSDB_CODE_INVALID_PARA;
3✔
1534
    return terrno;
3✔
1535
  }
1536

1537
  if (pFile->fp == NULL) {
145,265,607!
1538
    terrno = TSDB_CODE_INVALID_PARA;
×
1539
    return terrno;
×
1540
  }
1541

1542
  if (fgets(buf, maxSize, pFile->fp) == NULL) {
145,265,607✔
1543
    if (feof(pFile->fp)) {
55,052!
1544
      return 0;
55,052✔
1545
    } else {
1546
      terrno = TAOS_SYSTEM_ERROR(ferror(pFile->fp));
×
1547
      return terrno;
×
1548
    }
1549
  }
1550

1551
  return strlen(buf);
145,210,554✔
1552
}
1553

1554
int32_t taosEOFFile(TdFilePtr pFile) {
42,496,573✔
1555
  if (pFile == NULL) {
42,496,573✔
1556
    terrno = TSDB_CODE_INVALID_PARA;
2✔
1557
    return -1;
2✔
1558
  }
1559
  if (pFile->fp == NULL) {
42,496,571!
1560
    terrno = TSDB_CODE_INVALID_PARA;
×
1561
    return -1;
×
1562
  }
1563

1564
  return feof(pFile->fp);
42,496,571✔
1565
}
1566

1567
bool taosCheckAccessFile(const char *pathname, int32_t tdFileAccessOptions) {
825,940✔
1568
  if (pathname == NULL) {
825,940✔
1569
    terrno = TSDB_CODE_INVALID_PARA;
1✔
1570
    return false;  // invalid parameter
1✔
1571
  }
1572
  int flags = 0;
825,939✔
1573

1574
  if (tdFileAccessOptions & TD_FILE_ACCESS_EXIST_OK) {
825,939!
1575
    flags |= F_OK;
826,072✔
1576
  }
1577

1578
  if (tdFileAccessOptions & TD_FILE_ACCESS_READ_OK) {
825,939✔
1579
    flags |= R_OK;
41,480✔
1580
  }
1581

1582
  if (tdFileAccessOptions & TD_FILE_ACCESS_WRITE_OK) {
825,939✔
1583
    flags |= W_OK;
41,480✔
1584
  }
1585

1586
  if (tdFileAccessOptions & TD_FILE_ACCESS_EXEC_OK) {
825,939!
1587
    flags |= X_OK;
×
1588
  }
1589
#ifdef WINDOWS
1590
  return _access(pathname, flags) == 0;
1591
#else
1592
  return access(pathname, flags) == 0;
825,939✔
1593
#endif
1594
}
1595

1596
bool taosCheckExistFile(const char *pathname) { return taosCheckAccessFile(pathname, TD_FILE_ACCESS_EXIST_OK); };
784,459✔
1597

1598
int32_t taosCompressFile(char *srcFileName, char *destFileName) {
7✔
1599
  OS_PARAM_CHECK(srcFileName);
7✔
1600
  OS_PARAM_CHECK(destFileName);
6✔
1601
  int32_t   compressSize = 163840;
5✔
1602
  int32_t   ret = 0;
5✔
1603
  int32_t   len = 0;
5✔
1604
  gzFile    dstFp = NULL;
5✔
1605
  TdFilePtr pSrcFile = NULL;
5✔
1606

1607
  char *data = taosMemoryMalloc(compressSize);
5!
1608
  if (NULL == data) {
5!
1609
    return terrno;
×
1610
  }
1611

1612
  pSrcFile = taosOpenFile(srcFileName, TD_FILE_READ | TD_FILE_STREAM);
5✔
1613
  if (pSrcFile == NULL) {
5✔
1614
    ret = terrno;
1✔
1615
    goto cmp_end;
1✔
1616
  }
1617

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

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

1646
  while (!feof(pSrcFile->fp)) {
6✔
1647
    len = (int32_t)fread(data, 1, compressSize, pSrcFile->fp);
3✔
1648
    if (len > 0) {
3!
1649
      if (gzwrite(dstFp, data, len) == 0) {
3!
1650
        terrno = TAOS_SYSTEM_ERROR(ERRNO);
×
1651
        ret = terrno;
×
1652
        goto cmp_end;
×
1653
      }
1654
    }
1655
  }
1656

1657
cmp_end:
3✔
1658

1659
  if (fd >= 0) {
5✔
1660
    TAOS_SKIP_ERROR(close(fd));
4✔
1661
  }
1662
  if (pSrcFile) {
5✔
1663
    TAOS_SKIP_ERROR(taosCloseFile(&pSrcFile));
4✔
1664
  }
1665

1666
  if (dstFp) {
5✔
1667
    TAOS_SKIP_ERROR(gzclose(dstFp));
3✔
1668
  }
1669

1670
  taosMemoryFree(data);
5!
1671

1672
  return ret;
5✔
1673
}
1674

1675
int32_t taosSetFileHandlesLimit() {
21,765✔
1676
#ifdef WINDOWS
1677
  const int max_handles = 8192;
1678
  int       res = _setmaxstdio(max_handles);
1679
  return res == max_handles ? 0 : -1;
1680
#endif
1681
  return 0;
21,765✔
1682
}
1683

1684
int32_t taosLinkFile(char *src, char *dst) {
303✔
1685
#ifndef WINDOWS
1686
  if (-1 == link(src, dst)) {
303✔
1687
    terrno = TAOS_SYSTEM_ERROR(ERRNO);
1✔
1688
    return terrno;
1✔
1689
  }
1690
#endif
1691
  return 0;
302✔
1692
}
1693

1694
FILE *taosOpenCFile(const char *filename, const char *mode) {
671,032✔
1695
  if (filename == NULL || mode == NULL) {
671,032!
1696
    terrno = TSDB_CODE_INVALID_PARA;
×
1697
    return NULL;
2✔
1698
  }
1699
  STUB_RAND_IO_ERR(NULL)
1700
  FILE *f = fopen(filename, mode);
671,740✔
1701
  if (NULL == f) {
672,224!
UNCOV
1702
    terrno = TAOS_SYSTEM_ERROR(ERRNO);
×
1703
  }
1704
  return f;
672,225✔
1705
}
1706

1707
int taosSeekCFile(FILE *file, int64_t offset, int whence) {
385,085✔
1708
  if (NULL == file) {
385,085✔
1709
    terrno = TSDB_CODE_INVALID_PARA;
1✔
1710
    return terrno;
1✔
1711
  }
1712
#ifdef WINDOWS
1713
  return _fseeki64(file, offset, whence);
1714
#else
1715
  int     code = fseeko(file, offset, whence);
385,084✔
1716
  if (-1 == code) {
385,078!
1717
    terrno = TAOS_SYSTEM_ERROR(ERRNO);
×
1718
    code = terrno;
×
1719
  }
1720
  return code;
385,087✔
1721
#endif
1722
}
1723

1724
size_t taosReadFromCFile(void *buffer, size_t size, size_t count, FILE *stream) {
385,079✔
1725
  if (buffer == NULL || stream == NULL) {
385,079!
1726
    terrno = TSDB_CODE_INVALID_PARA;
×
1727
    return 0;
2✔
1728
  }
1729
  STUB_RAND_IO_ERR(terrno)
1730
  return fread(buffer, size, count, stream);
385,084✔
1731
}
1732

1733
#if 0
1734
size_t taosWriteToCFile(const void *ptr, size_t size, size_t nitems, FILE *stream) {
1735
  STUB_RAND_IO_ERR(terrno)
1736
  return fwrite(ptr, size, nitems, stream);
1737
}
1738
#endif
1739

1740
int taosCloseCFile(FILE *f) { return fclose(f); }
672,140✔
1741

1742
int taosSetAutoDelFile(char *path) {
672,224✔
1743
#ifdef WINDOWS
1744
  bool succ = SetFileAttributes(path, FILE_ATTRIBUTE_TEMPORARY);
1745
  if (succ) {
1746
    return 0;
1747
  } else {
1748
    terrno = TAOS_SYSTEM_WINAPI_ERROR(GetLastError());
1749
    return terrno;
1750
  }
1751
#else
1752
  if (-1 == unlink(path)) {
672,224!
1753
    terrno = TAOS_SYSTEM_ERROR(ERRNO);
×
1754
    return terrno;
×
1755
  }
1756
  return 0;
672,224✔
1757
#endif
1758
}
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