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

taosdata / TDengine / #4914

06 Jan 2026 01:30AM UTC coverage: 64.876% (-0.008%) from 64.884%
#4914

push

travis-ci

web-flow
merge: from main to 3.0 branch #34167

180 of 319 new or added lines in 14 files covered. (56.43%)

3475 existing lines in 124 files now uncovered.

194993 of 300563 relevant lines covered (64.88%)

116239151.85 hits per line

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

56.19
/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 <sys/uio.h>
44
#include <unistd.h>
45
#define LINUX_FILE_NO_TEXT_OPTION 0
46
#define O_TEXT                    LINUX_FILE_NO_TEXT_OPTION
47

48
#define _SEND_FILE_STEP_ 1000
49
#endif
50

51
typedef int32_t FileFd;
52

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

68
#define FILE_WITH_LOCK 1
69

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

84
void taosGetTmpfilePath(const char *inputTmpDir, const char *fileNamePrefix, char *dstPath) {
2,433,684✔
85
  if (inputTmpDir == NULL || fileNamePrefix == NULL) return;
2,433,684✔
86
#ifdef WINDOWS
87

88
  char tmpPath[PATH_MAX];
89

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

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

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

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

103
#else
104

105
  char    tmpPath[PATH_MAX];
2,431,854✔
106
  int32_t len = strlen(inputTmpDir);
2,433,074✔
107
  (void)memcpy(tmpPath, inputTmpDir, len);
2,433,074✔
108
  static uint64_t seqId = 0;
109

110
  if (tmpPath[len - 1] != '/') {
2,433,074✔
111
    tmpPath[len++] = '/';
×
112
  }
113

114
  snprintf(tmpPath + len, sizeof(tmpPath) - len, "%s%s%s", TD_TMP_FILE_PREFIX, fileNamePrefix, "-%d-%s");
2,423,752✔
115

116
  char rand[32] = {0};
2,427,558✔
117

118
  (void)snprintf(rand, sizeof(rand), "%" PRIu64, atomic_add_fetch_64(&seqId, 1));
2,439,174✔
119

120
  (void)snprintf(dstPath, PATH_MAX, tmpPath, taosGetPId(), rand);
2,437,318✔
121

122
#endif
123
}
124

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

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

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

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

164
    if (bytes == 0) break;
×
165

166
    size += bytes;
×
167

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

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

180
  TAOS_UNUSED(taosCloseFile(&pFileFrom));
×
181
  TAOS_UNUSED(taosCloseFile(&pFileTo));
×
182

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

188
  return size;
×
189

190
_err:
×
191

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

197
  terrno = code;
×
198
  return -1;
×
199
#endif
200
}
201

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

223
  return fp;
×
224
}
225

226
int32_t taosRemoveFile(const char *path) {
54,561,187✔
227
  OS_PARAM_CHECK(path);
54,561,187✔
228
  int32_t code = remove(path);
54,561,187✔
229
  if (-1 == code) {
54,565,263✔
230
    terrno = TAOS_SYSTEM_ERROR(ERRNO);
2,451,239✔
231
    return terrno;
2,448,007✔
232
  }
233
  return code;
52,114,024✔
234
}
235

236
int32_t taosRenameFile(const char *oldName, const char *newName) {
97,729,771✔
237
  OS_PARAM_CHECK(oldName);
97,729,771✔
238
  OS_PARAM_CHECK(newName);
97,729,771✔
239
#ifdef WINDOWS
240
  bool finished = false;
241

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

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

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

264
  CloseHandle(transactionHandle);
265

266
  return finished ? 0 : terrno;
267
#else
268
#ifdef TD_ASTRA // TD_ASTRA_TODO
269
  if (taosCheckExistFile(newName)) taosRemoveFile(newName);
270
#endif
271
  int32_t code = rename(oldName, newName);
97,729,771✔
272
  if (-1 == code) {
97,728,818✔
273
    terrno = TAOS_SYSTEM_ERROR(ERRNO);
17,511✔
274
    return terrno;
11,180✔
275
  }
276

277
  return TSDB_CODE_SUCCESS;
97,711,307✔
278
#endif
279
}
280

281
int32_t taosStatFile(const char *path, int64_t *size, int64_t *mtime, int64_t *atime) {
245,550,919✔
282
  OS_PARAM_CHECK(path);
245,550,919✔
283
#ifdef WINDOWS
284
  struct _stati64 fileStat;
285
  int32_t         code = _stati64(path, &fileStat);
286
#else
287
  struct stat fileStat;
245,472,294✔
288
  int32_t     code = stat(path, &fileStat);
245,550,188✔
289
#endif
290
  if (-1 == code) {
245,551,663✔
291
    terrno = TAOS_SYSTEM_ERROR(ERRNO);
15,126,558✔
292
    return terrno;
15,108,760✔
293
  }
294

295
  if (size != NULL) {
230,425,105✔
296
    *size = fileStat.st_size;
225,080,260✔
297
  }
298

299
  if (mtime != NULL) {
230,430,953✔
300
    *mtime = fileStat.st_mtime;
1,411,445✔
301
  }
302

303
  if (atime != NULL) {
230,430,953✔
304
    *atime = fileStat.st_atime;
×
305
  }
306

307
  return 0;
230,430,953✔
308
}
309

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

324
  if (diskid != NULL) {
616,432✔
325
    *diskid = fileStat.st_dev;
616,432✔
326
  }
327

328
  return 0;
616,432✔
329
}
330

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

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

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

352
#else
353
  if (pFile == NULL || pFile->fd < 0) {
7,441,935✔
354
    terrno = TSDB_CODE_INVALID_PARA;
1,391✔
355
    return terrno;
×
356
  }
357

358
  struct stat fileStat;
7,438,763✔
359
  int32_t     code = fstat(pFile->fd, &fileStat);
7,439,378✔
360
  if (-1 == code) {
7,441,318✔
361
    terrno = TAOS_SYSTEM_ERROR(ERRNO);
×
362
    return terrno;
×
363
  }
364

365
  if (stDev != NULL) {
7,441,318✔
366
    *stDev = fileStat.st_dev;
7,441,705✔
367
  }
368

369
  if (stIno != NULL) {
7,442,650✔
370
    *stIno = fileStat.st_ino;
7,442,650✔
371
  }
372
#endif
373

374
  return 0;
7,442,571✔
375
}
376

377
FILE *taosOpenFileForStream(const char *path, int32_t tdFileOptions) {
2,147,483,647✔
378
  if (path == NULL) {
2,147,483,647✔
379
    terrno = TSDB_CODE_INVALID_PARA;
×
380
    return NULL;
×
381
  }
382
  char *mode = NULL;
2,147,483,647✔
383
  if (tdFileOptions & TD_FILE_APPEND) {
2,147,483,647✔
384
    mode = (tdFileOptions & TD_FILE_TEXT) ? "at+" : "ab+";
1,111,752✔
385
  } else if (tdFileOptions & TD_FILE_TRUNC) {
2,147,483,647✔
386
    mode = (tdFileOptions & TD_FILE_TEXT) ? "wt+" : "wb+";
1,064,080✔
387
  } else if ((tdFileOptions & TD_FILE_READ) && !(tdFileOptions & TD_FILE_WRITE)) {
2,147,483,647✔
388
    mode = (tdFileOptions & TD_FILE_TEXT) ? "rt" : "rb";
2,147,483,647✔
389
  } else {
390
    mode = (tdFileOptions & TD_FILE_TEXT) ? "rt+" : "rb+";
×
391
  }
392
  if (tdFileOptions & TD_FILE_EXCL) {
2,147,483,647✔
393
    terrno = TSDB_CODE_INVALID_PARA;
×
394
    return NULL;
×
395
  }
396
  FILE *f = fopen(path, mode);
2,147,483,647✔
397
  if (NULL == f) {
2,147,483,647✔
398
    terrno = TAOS_SYSTEM_ERROR(ERRNO);
2,264,980✔
399
  }
400
  return f;
2,147,483,647✔
401
}
402

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

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

430
  shareMode |= FILE_SHARE_WRITE;
431

432
  access |= GENERIC_READ;
433

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

772
#else
773
int taosOpenFileNotStream(const char *path, int32_t tdFileOptions) {
858,156,335✔
774
  if (path == NULL) {
858,156,335✔
775
    terrno = TSDB_CODE_INVALID_PARA;
×
776
    return -1;
×
777
  }
778
  int access = O_BINARY;
858,156,335✔
779
  access |= (tdFileOptions & TD_FILE_CREATE) ? O_CREAT : 0;
858,156,335✔
780
  if ((tdFileOptions & TD_FILE_WRITE) && (tdFileOptions & TD_FILE_READ)) {
858,156,335✔
781
    access |= O_RDWR;
117,584,829✔
782
  } else if (tdFileOptions & TD_FILE_WRITE) {
740,571,506✔
783
    access |= O_WRONLY;
69,686,812✔
784
  } else if (tdFileOptions & TD_FILE_READ) {
670,884,694✔
785
    access |= O_RDONLY;
670,055,294✔
786
  }
787
  access |= (tdFileOptions & TD_FILE_TRUNC) ? O_TRUNC : 0;
858,156,335✔
788
  access |= (tdFileOptions & TD_FILE_APPEND) ? O_APPEND : 0;
858,156,335✔
789
  access |= (tdFileOptions & TD_FILE_TEXT) ? O_TEXT : 0;
858,156,335✔
790
  access |= (tdFileOptions & TD_FILE_EXCL) ? O_EXCL : 0;
858,156,335✔
791
  access |= (tdFileOptions & TD_FILE_CLOEXEC) ? O_CLOEXEC : 0;
858,156,335✔
792

793
  int fd = open(path, access, S_IRWXU | S_IRWXG | S_IRWXO);
858,156,335✔
794
  if (-1 == fd) {
858,563,488✔
795
    terrno = TAOS_SYSTEM_ERROR(ERRNO);
7,097,645✔
796
  }
797
  return fd;
858,060,682✔
798
}
799

800
int64_t taosReadFile(TdFilePtr pFile, void *buf, int64_t count) {
1,643,778,638✔
801
  if (pFile == NULL || buf == NULL) {
1,643,778,638✔
UNCOV
802
    terrno = TSDB_CODE_INVALID_PARA;
×
803
    return -1;
×
804
  }
805
  STUB_RAND_IO_ERR(terrno)
806
#if FILE_WITH_LOCK
807
  (void)taosThreadRwlockRdlock(&(pFile->rwlock));
1,644,145,309✔
808
#endif
809

810
  if (pFile->fd < 0) {
1,644,103,344✔
811
#if FILE_WITH_LOCK
UNCOV
812
    (void)taosThreadRwlockUnlock(&(pFile->rwlock));
×
813
#endif
814
    terrno = TSDB_CODE_INVALID_PARA;
×
815
    return -1;
×
816
  }
817

818
  int64_t leftbytes = count;
1,643,139,738✔
819
  int64_t readbytes;
820
  char   *tbuf = (char *)buf;
1,643,139,738✔
821
  int32_t code = 0;
1,643,139,738✔
822

823
  while (leftbytes > 0) {
2,147,483,647✔
824
#ifdef WINDOWS
825
    readbytes = _read(pFile->fd, (void *)tbuf, (uint32_t)leftbytes);
826
#else
827
    readbytes = read(pFile->fd, (void *)tbuf, (uint32_t)leftbytes);
1,645,517,663✔
828
#endif
829
    if (readbytes < 0) {
1,644,990,470✔
830
      if (ERRNO == EINTR) {
5,840✔
831
        continue;
×
832
      } else {
833
        code = TAOS_SYSTEM_ERROR(ERRNO);
5,840✔
834
#if FILE_WITH_LOCK
835
        (void)taosThreadRwlockUnlock(&(pFile->rwlock));
5,840✔
836
#endif
837
        terrno = code;
5,840✔
838
        return -1;
5,840✔
839
      }
840
    } else if (readbytes == 0) {
1,644,984,630✔
841
#if FILE_WITH_LOCK
842
      (void)taosThreadRwlockUnlock(&(pFile->rwlock));
2,357,007✔
843
#endif
844
      return (int64_t)(count - leftbytes);
2,357,007✔
845
    }
846

847
    leftbytes -= readbytes;
1,642,627,623✔
848
    tbuf += readbytes;
1,642,627,623✔
849
  }
850

851
#if FILE_WITH_LOCK
852
  (void)taosThreadRwlockUnlock(&(pFile->rwlock));
1,640,277,548✔
853
#endif
854

855
  return count;
1,641,779,023✔
856
}
857

858
int64_t taosWriteFile(TdFilePtr pFile, const void *buf, int64_t count) {
2,147,483,647✔
859
  STUB_RAND_IO_ERR(terrno)
860
  if (pFile == NULL || buf == NULL) {
2,147,483,647✔
UNCOV
861
    terrno = TSDB_CODE_INVALID_PARA;
×
862
    return 0;
×
863
  }
864
#if FILE_WITH_LOCK
865
  (void)taosThreadRwlockWrlock(&(pFile->rwlock));
2,147,483,647✔
866
#endif
867
  if (pFile->fd < 0) {
2,147,483,647✔
868
#if FILE_WITH_LOCK
869
    (void)taosThreadRwlockUnlock(&(pFile->rwlock));
×
870
#endif
871
    terrno = TSDB_CODE_INVALID_PARA;
×
872
    return 0;
×
873
  }
874

875
  int64_t nleft = count;
2,147,483,647✔
876
  int64_t nwritten = 0;
2,147,483,647✔
877
  char   *tbuf = (char *)buf;
2,147,483,647✔
878
  int32_t code = 0;
2,147,483,647✔
879

880
  while (nleft > 0) {
2,147,483,647✔
881
    nwritten = write(pFile->fd, (void *)tbuf, (uint32_t)nleft);
2,147,483,647✔
882
    if (nwritten < 0) {
2,147,483,647✔
883
      if (ERRNO == EINTR) {
×
884
        continue;
×
885
      }
886
      code = TAOS_SYSTEM_ERROR(ERRNO);
×
887
#if FILE_WITH_LOCK
888
      (void)taosThreadRwlockUnlock(&(pFile->rwlock));
×
889
#endif
890
      terrno = code;
×
891
      return -1;
×
892
    }
893
    nleft -= nwritten;
2,147,483,647✔
894
    tbuf += nwritten;
2,147,483,647✔
895
  }
896

897
#if FILE_WITH_LOCK
898
  (void)taosThreadRwlockUnlock(&(pFile->rwlock));
2,147,483,647✔
899
#endif
900

901
  return count;
2,147,483,647✔
902
}
903

904
int64_t taosPWriteFile(TdFilePtr pFile, const void *buf, int64_t count, int64_t offset) {
176,750,316✔
905
  STUB_RAND_IO_ERR(terrno)
906
  if (pFile == NULL || buf == NULL) {
176,750,316✔
907
    terrno = TSDB_CODE_INVALID_PARA;
×
908
    return 0;
×
909
  }
910

911
  int32_t code = 0;
176,790,038✔
912
#if FILE_WITH_LOCK
913
  (void)taosThreadRwlockWrlock(&(pFile->rwlock));
176,790,038✔
914
#endif
915

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

951
  if (code) {
176,794,103✔
952
    terrno = code;
×
953
  }
954

955
  return ret;
176,804,682✔
956
}
957

958
int64_t taosLSeekFile(TdFilePtr pFile, int64_t offset, int32_t whence) {
2,147,483,647✔
959
  if (pFile == NULL || pFile->fd < 0) {
2,147,483,647✔
UNCOV
960
    terrno = TSDB_CODE_INVALID_PARA;
×
961
    return -1;
×
962
  }
963
#if FILE_WITH_LOCK
964
  (void)taosThreadRwlockRdlock(&(pFile->rwlock));
2,147,483,647✔
965
#endif
966

967
  int32_t code = 0;
2,147,483,647✔
968

969
  int64_t ret = lseek(pFile->fd, offset, whence);
2,147,483,647✔
970
  if (-1 == ret) {
2,147,483,647✔
971
    code = TAOS_SYSTEM_ERROR(ERRNO);
×
972
  }
973

974
#if FILE_WITH_LOCK
975
  (void)taosThreadRwlockUnlock(&(pFile->rwlock));
2,147,483,647✔
976
#endif
977

978
  if (code) {
2,147,483,647✔
979
    terrno = code;
×
980
    return -1;
×
981
  }
982

983
  return ret;
2,147,483,647✔
984
}
985

986
int32_t taosFStatFile(TdFilePtr pFile, int64_t *size, int64_t *mtime) {
23,986,676✔
987
  if (pFile == NULL) {
23,986,676✔
988
    terrno = TSDB_CODE_INVALID_PARA;
×
989
    return terrno;
×
990
  }
991

992
  if (pFile->fd < 0) {
23,986,676✔
993
    terrno = TSDB_CODE_INVALID_PARA;
×
994
    return terrno;
×
995
  }
996

997
  struct stat fileStat;
23,971,017✔
998
  int32_t     code = fstat(pFile->fd, &fileStat);
23,986,906✔
999
  if (-1 == code) {
23,985,109✔
1000
    terrno = TAOS_SYSTEM_ERROR(ERRNO);
×
1001
    return terrno;
×
1002
  }
1003

1004
  if (size != NULL) {
23,985,109✔
1005
    *size = fileStat.st_size;
23,986,667✔
1006
  }
1007

1008
  if (mtime != NULL) {
23,988,520✔
1009
    *mtime = fileStat.st_mtime;
×
1010
  }
1011

1012
  return 0;
23,988,520✔
1013
}
1014

1015
int32_t taosLockFile(TdFilePtr pFile) {
4,409,781✔
1016
  if (NULL == pFile || pFile->fd < 0) {
4,409,781✔
1017
    terrno = TSDB_CODE_INVALID_PARA;
×
1018
    return terrno;
×
1019
  }
1020
#ifndef TD_ASTRA
1021
  int32_t code = (int32_t)flock(pFile->fd, LOCK_EX | LOCK_NB);
4,409,781✔
1022
  if (-1 == code) {
4,409,781✔
1023
    terrno = TAOS_SYSTEM_ERROR(ERRNO);
1,207,142✔
1024
    return terrno;
1,207,142✔
1025
  }
1026
#else // TD_ASTRA_TODO
1027
  struct flock lock;
1028
  lock.l_type = F_WRLCK;
1029
  lock.l_whence = SEEK_SET;
1030
  lock.l_start = 0;
1031
  lock.l_len = 0;
1032
  int32_t code = fcntl(pFile->fd, F_SETLK, &lock);
1033
  if (-1 == code) {
1034
    //    terrno = TAOS_SYSTEM_ERROR(ERRNO); // TD_ASTRA_TODO
1035
    //    return terrno;                     // TD_ASTRA_TODO
1036
  }
1037
#endif
1038
  return 0;
3,202,639✔
1039
}
1040

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

1067
int32_t taosFtruncateFile(TdFilePtr pFile, int64_t l_size) {
49,616✔
1068
  if (NULL == pFile || pFile->fd < 0) {
49,616✔
1069
    terrno = TSDB_CODE_INVALID_PARA;
×
1070
    return terrno;
×
1071
  }
1072

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

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

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

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

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

1124
#else  // for linux
1125

1126
  int64_t leftbytes = size;
65,758✔
1127
  int64_t sentbytes;
1128

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

1146
    leftbytes -= sentbytes;
65,758✔
1147
  }
1148

1149
  return size;
65,758✔
1150
#endif
1151
}
1152

1153
bool lastErrorIsFileNotExist() { return terrno == TAOS_SYSTEM_ERROR(ENOENT); }
3,039,953✔
1154

1155
#endif  // WINDOWS
1156

1157
TdFilePtr taosOpenFile(const char *path, int32_t tdFileOptions) {
2,147,483,647✔
1158
  if (path == NULL) {
2,147,483,647✔
1159
    terrno = TSDB_CODE_INVALID_PARA;
×
1160
    return NULL;
×
1161
  }
1162
  STUB_RAND_IO_ERR(NULL)
1163
  FILE *fp = NULL;
2,147,483,647✔
1164
#ifdef WINDOWS
1165
  HANDLE hFile = NULL;
1166
#else
1167
  int fd = -1;
2,147,483,647✔
1168
#endif
1169
  if (tdFileOptions & TD_FILE_STREAM) {
2,147,483,647✔
1170
    fp = taosOpenFileForStream(path, tdFileOptions);
2,147,483,647✔
1171
    if (fp == NULL) return NULL;
2,147,483,647✔
1172
  } else {
1173
#ifdef WINDOWS
1174
    hFile = taosOpenFileNotStream(path, tdFileOptions);
1175
    if (hFile == INVALID_HANDLE_VALUE) return NULL;
1176
#else
1177
    fd = taosOpenFileNotStream(path, tdFileOptions);
858,274,122✔
1178
    if (fd == -1) return NULL;
858,069,674✔
1179
#endif
1180
  }
1181

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

1194
#if FILE_WITH_LOCK
1195
  (void)taosThreadRwlockInit(&(pFile->rwlock), NULL);
2,147,483,647✔
1196
#endif
1197
  pFile->fp = fp;
2,147,483,647✔
1198

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

1218
  return pFile;
2,147,483,647✔
1219
}
1220

1221
int32_t taosCloseFile(TdFilePtr *ppFile) {
2,147,483,647✔
1222
  int32_t code = 0;
2,147,483,647✔
1223
  if (ppFile == NULL || *ppFile == NULL) {
2,147,483,647✔
1224
    return 0;
736,042,691✔
1225
  }
1226
#if FILE_WITH_LOCK
1227
  (void)taosThreadRwlockWrlock(&((*ppFile)->rwlock));
2,147,483,647✔
1228
#endif
1229
  if ((*ppFile)->fp != NULL) {
2,147,483,647✔
1230
    TAOS_UNUSED(fflush((*ppFile)->fp));
2,147,483,647✔
1231
    TAOS_UNUSED(fclose((*ppFile)->fp));
2,147,483,647✔
1232
    (*ppFile)->fp = NULL;
2,147,483,647✔
1233
  }
1234
#ifdef WINDOWS
1235
  if ((*ppFile)->hFile != NULL) {
1236
    // FlushFileBuffers((*ppFile)->hFile);
1237
    if (!CloseHandle((*ppFile)->hFile)) {
1238
      terrno = TAOS_SYSTEM_WINAPI_ERROR(GetLastError());
1239
      code = -1;
1240
    }
1241
    (*ppFile)->hFile = NULL;
1242
#else
1243
  if ((*ppFile)->fd >= 0) {
2,147,483,647✔
1244
    // warning: never fsync silently in base lib
1245
    /*fsync((*ppFile)->fd);*/
1246
    code = close((*ppFile)->fd);
851,352,428✔
1247
    if (-1 == code) {
851,818,909✔
1248
      terrno = TAOS_SYSTEM_ERROR(ERRNO);
3✔
1249
    }
1250
    (*ppFile)->fd = -1;
851,818,906✔
1251
#endif
1252
  }
1253
#if FILE_WITH_LOCK
1254
  (void)taosThreadRwlockUnlock(&((*ppFile)->rwlock));
2,147,483,647✔
1255
  (void)taosThreadRwlockDestroy(&((*ppFile)->rwlock));
2,147,483,647✔
1256
#endif
1257
  taosMemoryFree(*ppFile);
2,147,483,647✔
1258
  *ppFile = NULL;
2,147,483,647✔
1259
  return code;
2,147,483,647✔
1260
}
1261

1262
int64_t taosPReadFile(TdFilePtr pFile, void *buf, int64_t count, int64_t offset) {
140,718,302✔
1263
  STUB_RAND_IO_ERR(terrno)
1264
  if (pFile == NULL) {
140,718,302✔
1265
    terrno = TSDB_CODE_INVALID_PARA;
×
1266
    return -1;
×
1267
  }
1268

1269
  int32_t code = 0;
140,718,302✔
1270

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

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

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

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

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

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

1338
  if (code) {
140,725,489✔
1339
    terrno = code;
×
1340
    return -1;
×
1341
  }
1342

1343
  return ret;
140,725,489✔
1344
}
1345

1346
int32_t taosFsyncFile(TdFilePtr pFile) {
326,577,619✔
1347
  if (pFile == NULL) {
326,577,619✔
1348
    return 0;
902,393✔
1349
  }
1350

1351
  int32_t code = 0;
325,675,226✔
1352
  // this implementation is WRONG
1353
  // fflush is not a replacement of fsync
1354
  if (pFile->fp != NULL) {
325,675,226✔
1355
    code = fflush(pFile->fp);
58,159✔
1356
    if (0 != code) {
58,159✔
1357
      terrno = TAOS_SYSTEM_ERROR(ERRNO);
×
1358
      return terrno;
×
1359
    }
1360

1361
    return 0;
58,159✔
1362
  }
1363

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

1390
  return 0;
325,656,864✔
1391
}
1392

1393
void taosFprintfFile(TdFilePtr pFile, const char *format, ...) {
2,147,483,647✔
1394
  if (pFile == NULL || pFile->fp == NULL) {
2,147,483,647✔
1395
    return;
2,147,483,647✔
1396
  }
1397
  va_list ap;
2,147,483,647✔
1398
  va_start(ap, format);
2,147,483,647✔
1399
  (void)vfprintf(pFile->fp, format, ap);
2,147,483,647✔
1400
  va_end(ap);
2,147,483,647✔
1401
}
1402

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

1411
int32_t taosUmaskFile(int32_t maskVal) {
5,325,423✔
1412
#ifdef WINDOWS
1413
  return 0;
1414
#else
1415
  return umask(maskVal);
5,325,423✔
1416
#endif
1417
}
1418

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

1423
  if (pFile == NULL || ptrBuf == NULL) {
168,603✔
1424
    terrno = TSDB_CODE_INVALID_PARA;
×
1425
    goto END;
×
1426
  }
1427
  if (*ptrBuf != NULL) {
168,603✔
1428
    taosMemoryFreeClear(*ptrBuf);
165,989✔
1429
  }
1430

1431
  if (pFile->fp == NULL) {
168,603✔
1432
    terrno = TSDB_CODE_INVALID_PARA;
×
1433
    goto END;
×
1434
  }
1435

1436
#if FILE_WITH_LOCK
1437
  (void)taosThreadRwlockRdlock(&(pFile->rwlock));
168,603✔
1438
#endif
1439

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

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

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

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

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

1476
    *ptrBuf = newBuf;
1477
  }
1478

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

1519
END:
168,603✔
1520

1521
#if FILE_WITH_LOCK
1522
  (void)taosThreadRwlockUnlock(&(pFile->rwlock));
168,603✔
1523
#endif
1524

1525
  return ret;
168,603✔
1526
}
1527

1528
int64_t taosGetsFile(TdFilePtr pFile, int32_t maxSize, char *__restrict buf) {
2,147,483,647✔
1529
  if (pFile == NULL || buf == NULL) {
2,147,483,647✔
1530
    terrno = TSDB_CODE_INVALID_PARA;
×
1531
    return terrno;
×
1532
  }
1533

1534
  if (pFile->fp == NULL) {
2,147,483,647✔
1535
    terrno = TSDB_CODE_INVALID_PARA;
×
1536
    return terrno;
×
1537
  }
1538

1539
  if (fgets(buf, maxSize, pFile->fp) == NULL) {
2,147,483,647✔
1540
    if (feof(pFile->fp)) {
4,227,019✔
1541
      return 0;
4,227,019✔
1542
    } else {
1543
      terrno = TAOS_SYSTEM_ERROR(ferror(pFile->fp));
×
1544
      return terrno;
×
1545
    }
1546
  }
1547

1548
  return strlen(buf);
2,147,483,647✔
1549
}
1550

1551
int32_t taosEOFFile(TdFilePtr pFile) {
2,147,483,647✔
1552
  if (pFile == NULL) {
2,147,483,647✔
1553
    terrno = TSDB_CODE_INVALID_PARA;
×
1554
    return -1;
×
1555
  }
1556
  if (pFile->fp == NULL) {
2,147,483,647✔
1557
    terrno = TSDB_CODE_INVALID_PARA;
×
1558
    return -1;
×
1559
  }
1560

1561
  return feof(pFile->fp);
2,147,483,647✔
1562
}
1563

1564
bool taosCheckAccessFile(const char *pathname, int32_t tdFileAccessOptions) {
172,400,264✔
1565
  if (pathname == NULL) {
172,400,264✔
1566
    terrno = TSDB_CODE_INVALID_PARA;
×
1567
    return false;  // invalid parameter
×
1568
  }
1569
  int flags = 0;
172,400,264✔
1570

1571
  if (tdFileAccessOptions & TD_FILE_ACCESS_EXIST_OK) {
172,400,264✔
1572
    flags |= F_OK;
172,397,003✔
1573
  }
1574

1575
  if (tdFileAccessOptions & TD_FILE_ACCESS_READ_OK) {
172,400,264✔
1576
    flags |= R_OK;
4,616,898✔
1577
  }
1578

1579
  if (tdFileAccessOptions & TD_FILE_ACCESS_WRITE_OK) {
172,400,264✔
1580
    flags |= W_OK;
4,616,898✔
1581
  }
1582

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

1593
bool taosCheckExistFile(const char *pathname) { return taosCheckAccessFile(pathname, TD_FILE_ACCESS_EXIST_OK); };
167,788,379✔
1594

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

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

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

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

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

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

1654
cmp_end:
×
1655

1656
  if (fd >= 0) {
×
1657
    TAOS_SKIP_ERROR(close(fd));
×
1658
  }
1659
  if (pSrcFile) {
×
1660
    TAOS_SKIP_ERROR(taosCloseFile(&pSrcFile));
×
1661
  }
1662

1663
  if (dstFp) {
×
1664
    TAOS_SKIP_ERROR(gzclose(dstFp));
×
1665
  }
1666

1667
  taosMemoryFree(data);
×
1668

1669
  return ret;
×
1670
}
1671

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

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

1691
int32_t taosSymLink(const char *target, const char *linkpath) {
5,060✔
1692
#ifdef WINDOWS
1693
  DWORD attributes = GetFileAttributesA(target);
1694
  BOOL  isDir = (attributes != INVALID_FILE_ATTRIBUTES) && (attributes & FILE_ATTRIBUTE_DIRECTORY);
1695
  if (!CreateSymbolicLinkA(linkpath, target, isDir ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0)) {
1696
    return (terrno = TAOS_SYSTEM_WINAPI_ERROR(GetLastError()));
1697
  }
1698
#else
1699
  if (symlink(target, linkpath) == -1) {
5,060✔
1700
    return (terrno = TAOS_SYSTEM_ERROR(ERRNO));
×
1701
  }
1702
#endif
1703
  return 0;
5,060✔
1704
}
1705

1706
FILE *taosOpenCFile(const char *filename, const char *mode) {
2,401,846✔
1707
  if (filename == NULL || mode == NULL) {
2,401,846✔
1708
    terrno = TSDB_CODE_INVALID_PARA;
4,880✔
1709
    return NULL;
×
1710
  }
1711
  STUB_RAND_IO_ERR(NULL)
1712
  FILE *f = fopen(filename, mode);
2,396,966✔
1713
  if (NULL == f) {
2,406,580✔
1714
    terrno = TAOS_SYSTEM_ERROR(ERRNO);
×
1715
  }
1716
  return f;
2,406,580✔
1717
}
1718

1719
int taosSeekCFile(FILE *file, int64_t offset, int whence) {
1,989,980✔
1720
  if (NULL == file) {
1,989,980✔
1721
    terrno = TSDB_CODE_INVALID_PARA;
×
1722
    return terrno;
×
1723
  }
1724
#ifdef WINDOWS
1725
  return _fseeki64(file, offset, whence);
1726
#else
1727
  int     code = fseeko(file, offset, whence);
1,989,980✔
1728
  if (-1 == code) {
1,990,444✔
1729
    terrno = TAOS_SYSTEM_ERROR(ERRNO);
×
1730
    code = terrno;
×
1731
  }
1732
  return code;
1,990,444✔
1733
#endif
1734
}
1735

1736
size_t taosReadFromCFile(void *buffer, size_t size, size_t count, FILE *stream) {
1,990,444✔
1737
  if (buffer == NULL || stream == NULL) {
1,990,444✔
1738
    terrno = TSDB_CODE_INVALID_PARA;
×
1739
    return 0;
×
1740
  }
1741
  STUB_RAND_IO_ERR(terrno)
1742
  return fread(buffer, size, count, stream);
1,990,444✔
1743
}
1744

1745
#if 0
1746
size_t taosWriteToCFile(const void *ptr, size_t size, size_t nitems, FILE *stream) {
1747
  STUB_RAND_IO_ERR(terrno)
1748
  return fwrite(ptr, size, nitems, stream);
1749
}
1750
#endif
1751

1752
int taosCloseCFile(FILE *f) { return fclose(f); }
2,406,580✔
1753

1754
int taosSetAutoDelFile(char *path) {
2,406,580✔
1755
#ifdef WINDOWS
1756
  bool succ = SetFileAttributes(path, FILE_ATTRIBUTE_TEMPORARY);
1757
  if (succ) {
1758
    return 0;
1759
  } else {
1760
    terrno = TAOS_SYSTEM_WINAPI_ERROR(GetLastError());
1761
    return terrno;
1762
  }
1763
#else
1764
  if (-1 == unlink(path)) {
2,406,580✔
1765
    terrno = TAOS_SYSTEM_ERROR(ERRNO);
×
1766
    return terrno;
×
1767
  }
1768
  return 0;
2,406,580✔
1769
#endif
1770
}
1771

1772
int64_t taosWritevFile(TdFilePtr pFile, const TaosIOVec *iov, int iovcnt) {
×
1773
  if (pFile == NULL || iov == NULL || iovcnt <= 0) {
×
1774
    terrno = TSDB_CODE_INVALID_PARA;
×
1775
    return -1;
×
1776
  }
1777
#if FILE_WITH_LOCK
1778
  (void)taosThreadRwlockWrlock(&(pFile->rwlock));
×
1779
#endif
1780

1781
#ifdef __linux__
1782
  if (pFile->fd < 0) {
×
1783
#if FILE_WITH_LOCK
1784
    (void)taosThreadRwlockUnlock(&(pFile->rwlock));
×
1785
#endif
1786
    terrno = TSDB_CODE_INVALID_PARA;
×
1787
    return -1;
×
1788
  }
1789
  ssize_t written = writev(pFile->fd, iov, iovcnt);
×
1790
  if (written < 0) {
×
1791
    terrno = TAOS_SYSTEM_ERROR(ERRNO);
×
1792
  }
1793
#if FILE_WITH_LOCK
1794
  (void)taosThreadRwlockUnlock(&(pFile->rwlock));
×
1795
#endif
1796
  return (int64_t)written;
×
1797
#elif defined(WINDOWS)
1798
  if (pFile == NULL || pFile->hFile == NULL) {
1799
#if FILE_WITH_LOCK
1800
    (void)taosThreadRwlockUnlock(&(pFile->rwlock));
1801
#endif
1802
    terrno = TSDB_CODE_INVALID_PARA;
1803
    return -1;
1804
  }
1805
  int64_t totalWritten = 0;
1806
  for (int i = 0; i < iovcnt; ++i) {
1807
    TaosIOVec *vec = &iov[i];
1808
    if (vec->iov_len <= 0) continue;
1809
    DWORD written;
1810
    if (!WriteFile(pFile->hFile, vec->iov_base, vec->iov_len, &written, NULL)) {
1811
      SET_ERRNO(GetLastError());
1812
      terrno = TAOS_SYSTEM_WINAPI_ERROR(ERRNO);
1813
      written = -1;
1814
      break;
1815
    }
1816
    totalWritten += written;
1817
  }
1818
#if FILE_WITH_LOCK
1819
  (void)taosThreadRwlockUnlock(&(pFile->rwlock));
1820
#endif
1821
  if (totalWritten < 0) {
1822
    return -1;
1823
  }
1824
  return (int64_t)totalWritten;
1825
#else
1826
  if (pFile->fd < 0) {
1827
#if FILE_WITH_LOCK
1828
    (void)taosThreadRwlockUnlock(&(pFile->rwlock));
1829
#endif
1830
    terrno = TSDB_CODE_INVALID_PARA;
1831
    return -1;
1832
  }
1833
  int64_t totalWritten = 0;
1834
  for (int i = 0; i < iovcnt; ++i) {
1835
    const struct iovec *vec = &iov[i];
1836
    if (vec->iov_len <= 0) continue;
1837
    ssize_t written = write(pFile->fd, vec->iov_base, vec->iov_len);
1838
    if (written < 0) {
1839
      if (ERRNO == EINTR || ERRNO == EAGAIN || ERRNO == EWOULDBLOCK) {
1840
        continue;
1841
      } else {
1842
        terrno = TAOS_SYSTEM_ERROR(ERRNO);
1843
        totalWritten = -1;
1844
        break;
1845
      }
1846
    }
1847
    totalWritten += written;
1848
  }
1849
#if FILE_WITH_LOCK
1850
  (void)taosThreadRwlockUnlock(&(pFile->rwlock));
1851
#endif
1852
  if (totalWritten < 0) {
1853
    return -1;
1854
  }
1855
  return (int64_t)totalWritten;
1856
#endif
1857
}
1858

1859
// ============================================================================
1860
// Encrypted File Operations Implementation
1861
// ============================================================================
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