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

taosdata / TDengine / #5011

03 Apr 2026 03:59PM UTC coverage: 72.3% (+0.008%) from 72.292%
#5011

push

travis-ci

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

4053 of 5985 new or added lines in 68 files covered. (67.72%)

732 existing lines in 143 files now uncovered.

257430 of 356056 relevant lines covered (72.3%)

131834103.52 hits per line

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

92.54
/source/os/src/osDir.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

16
#define _DEFAULT_SOURCE
17
#define ALLOW_FORBID_FUNC
18

19
#include "os.h"
20

21
#ifdef WINDOWS
22

23
#include <windows.h>
24

25
typedef struct TdDirEntry {
26
  WIN32_FIND_DATA findFileData;
27
} TdDirEntry;
28

29
typedef struct TdDir {
30
  TdDirEntry dirEntry;
31
  HANDLE     hFind;
32
} TdDir;
33

34
enum {
35
  WRDE_NOSPACE = 1, /* Ran out of memory.  */
36
  WRDE_BADCHAR,     /* A metachar appears in the wrong place.  */
37
  WRDE_BADVAL,      /* Undefined var reference with WRDE_UNDEF.  */
38
  WRDE_CMDSUB,      /* Command substitution with WRDE_NOCMD.  */
39
  WRDE_SYNTAX       /* Shell syntax error.  */
40
};
41

42
int32_t wordexp(char *words, wordexp_t *pwordexp, int32_t flags) {
43
  pwordexp->we_offs = 0;
44
  pwordexp->we_wordc = 1;
45
  pwordexp->we_wordv[0] = pwordexp->wordPos;
46

47
  (void)memset(pwordexp->wordPos, 0, 1025);
48
  if (_fullpath(pwordexp->wordPos, words, 1024) == NULL) {
49
    pwordexp->we_wordv[0] = words;
50
    printf("failed to parse relative path:%s to abs path\n", words);
51
    return -1;
52
  }
53

54
  // printf("parse relative path:%s to abs path:%s\n", words, pwordexp->wordPos);
55
  return 0;
56
}
57

58
void wordfree(wordexp_t *pwordexp) {}
59

60
#elif defined(DARWIN)
61
#include <dlfcn.h>
62
#include <dirent.h>
63
#include <fcntl.h>
64
#include <sys/stat.h>
65
#include <unistd.h>
66
#include <wordexp.h>
67

68
typedef struct dirent dirent;
69
typedef struct dirent TdDirEntry;
70

71
typedef struct TdDir {
72
  TdDirEntry    dirEntry;
73
  TdDirEntry    dirEntry1;
74
  TdDirEntryPtr dirEntryPtr;
75
  DIR          *pDir;
76
} TdDir;
77

78
#else
79

80
#include <dlfcn.h>
81
#include <dirent.h>
82
#include <fcntl.h>
83
#include <sys/stat.h>
84
#include <unistd.h>
85
#ifndef TD_ASTRA
86
#include <wordexp.h>
87
#endif
88

89
typedef struct dirent dirent;
90
typedef struct DIR    TdDir;
91
typedef struct dirent TdDirEntry;
92

93
#endif
94

95
#define TDDIRMAXLEN 1024
96

97
#ifdef WINDOWS
98
static bool taosDirEntryIsReparsePoint(TdDirEntryPtr pDirEntry) {
99
  if (pDirEntry == NULL) return false;
100
  return (pDirEntry->findFileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0;
101
}
102
#endif
103

104
void taosRemoveDir(const char *dirname) {
18,628,647✔
105
  TdDirPtr pDir = taosOpenDir(dirname);
18,628,647✔
106
  if (pDir == NULL) return;
18,628,647✔
107

108
  TdDirEntryPtr de = NULL;
18,558,085✔
109
  while ((de = taosReadDir(pDir)) != NULL) {
103,758,290✔
110
    if (strcmp(taosGetDirEntryName(de), ".") == 0 || strcmp(taosGetDirEntryName(de), "..") == 0) continue;
85,200,205✔
111

112
    char filename[1024] = {0};
48,084,035✔
113
    (void)snprintf(filename, sizeof(filename), "%s%s%s", dirname, TD_DIRSEP, taosGetDirEntryName(de));
48,084,035✔
114
    if (taosDirEntryIsDir(de)) {
48,084,035✔
115
      taosRemoveDir(filename);
15,414,872✔
116
#ifdef WINDOWS
117
    } else if (taosDirEntryIsReparsePoint(de)) {
118
      // Remove junction/symlink directory without following it
119
      TAOS_UNUSED(RemoveDirectoryA(filename));
120
#endif
121
    } else {
122
      TAOS_UNUSED(taosRemoveFile(filename));
32,669,163✔
123
      // printf("file:%s is removed\n", filename);
124
    }
125
  }
126

127
  TAOS_UNUSED(taosCloseDir(&pDir));
18,558,085✔
128
  TAOS_UNUSED(rmdir(dirname));
18,558,085✔
129

130
  // printf("dir:%s is removed\n", dirname);
131
  return;
18,558,085✔
132
}
133

134
bool taosDirExist(const char *dirname) {
88,128,499✔
135
  if (dirname == NULL || strlen(dirname) >= TDDIRMAXLEN) return false;
88,128,499✔
136
  return taosCheckExistFile(dirname);
88,136,753✔
137
}
138

139
int32_t taosMkDir(const char *dirname) {
62,120,967✔
140
  if (taosDirExist(dirname)) return 0;
62,120,967✔
141
#ifdef WINDOWS
142
  int32_t code = _mkdir(dirname, 0755);
143
#elif defined(DARWIN)
144
  int32_t code = mkdir(dirname, 0777);
145
#else
146
  int32_t code = mkdir(dirname, 0755);
27,537,202✔
147
#endif
148
  if (-1 == code) {
27,542,018✔
149
    if (ERRNO == EEXIST) {
46,381✔
150
      return 0;
1,726✔
151
    } else {
152
      terrno = TAOS_SYSTEM_ERROR(ERRNO);
44,655✔
153
      code = terrno;
44,655✔
154
    }
155
  }
156

157
  return code;
27,536,098✔
158
}
159

160
int32_t taosMulMkDir(const char *dirname) {
8,076,194✔
161
  if (dirname == NULL || strlen(dirname) >= TDDIRMAXLEN) return -1;
8,076,194✔
162
  char    temp[TDDIRMAXLEN];
8,028,399✔
163
  char   *pos = temp;
8,075,794✔
164
  int32_t code = 0;
8,075,794✔
165
#ifdef WINDOWS
166
  code = taosRealPath(dirname, temp, sizeof(temp));
167
  if (code != 0) {
168
    return code;
169
  }
170
  if (temp[1] == ':') pos += 3;
171
#else
172
  tstrncpy(temp, dirname, sizeof(temp));
8,075,794✔
173
#endif
174

175
  if (taosDirExist(temp)) return code;
8,075,794✔
176

177
  if (strncmp(temp, TD_DIRSEP, 1) == 0) {
909,069✔
178
    pos += 1;
908,469✔
179
  } else if (strncmp(temp, "." TD_DIRSEP, 2) == 0) {
600✔
180
    pos += 2;
200✔
181
  }
182

183
  for (; *pos != '\0'; pos++) {
33,116,330✔
184
    if (*pos == TD_DIRSEP[0]) {
32,207,461✔
185
      *pos = '\0';
4,290,706✔
186
#ifdef WINDOWS
187
      code = _mkdir(temp, 0755);
188
#elif defined(DARWIN)
189
      code = mkdir(temp, 0777);
190
#else
191
      code = mkdir(temp, 0755);
4,290,706✔
192
#endif
193
      if (code < 0 && ERRNO != EEXIST) {
4,290,706✔
194
        terrno = TAOS_SYSTEM_ERROR(ERRNO);
200✔
195
        return code;
200✔
196
      }
197
      *pos = TD_DIRSEP[0];
4,290,506✔
198
    }
199
  }
200

201
  if (*(pos - 1) != TD_DIRSEP[0]) {
908,869✔
202
#ifdef WINDOWS
203
    code = _mkdir(temp, 0755);
204
#elif defined(DARWIN)
205
    code = mkdir(dirname, 0777);
206
#else
207
    code = mkdir(temp, 0755);
585,838✔
208
#endif
209
    if (code < 0 && ERRNO != EEXIST) {
585,838✔
210
      terrno = TAOS_SYSTEM_ERROR(ERRNO);
200✔
211
      return code;
200✔
212
    }
213
  }
214

215
  return 0;
908,669✔
216
}
217

218
int32_t taosMulModeMkDir(const char *dirname, int32_t mode, bool checkAccess) {
13,056,655✔
219
  if (dirname == NULL || strlen(dirname) >= TDDIRMAXLEN) {
13,056,655✔
220
    terrno = TSDB_CODE_INVALID_PARA;
1,108✔
221
    return terrno;
400✔
222
  }
223
  char    temp[TDDIRMAXLEN];
13,004,474✔
224
  char   *pos = temp;
13,055,600✔
225
  int32_t code = 0;
13,055,600✔
226
#ifdef WINDOWS
227
  code = taosRealPath(dirname, temp, sizeof(temp));
228
  if (code != 0) {
229
    return code;
230
  }
231
  if (temp[1] == ':') pos += 3;
232
#else
233
  tstrncpy(temp, dirname, sizeof(temp));
13,055,600✔
234
#endif
235

236
  if (taosDirExist(temp)) {
13,055,851✔
237
    if (checkAccess &&
13,440,401✔
238
        taosCheckAccessFile(temp, TD_FILE_ACCESS_EXIST_OK | TD_FILE_ACCESS_READ_OK | TD_FILE_ACCESS_WRITE_OK)) {
3,918,119✔
239
      return 0;
3,918,119✔
240
    }
241
#ifndef TD_ASTRA  // TD_ASTRA_TODO  IMPORTANT
242
    code = chmod(temp, mode);
5,604,163✔
243
    if (-1 == code) {
5,604,073✔
UNCOV
244
      struct stat statbuf = {0};
×
UNCOV
245
      code = stat(temp, &statbuf);
×
246
      if (code != 0 || (statbuf.st_mode & mode) != mode) {
×
247
        terrno = TAOS_SYSTEM_ERROR(ERRNO);
×
248
        return terrno;
×
249
      }
250
    }
251
#else
252
    return 0;
253
#endif
254
  }
255

256
  if (strncmp(temp, TD_DIRSEP, 1) == 0) {
9,137,442✔
257
    pos += 1;
9,134,411✔
258
  } else if (strncmp(temp, "." TD_DIRSEP, 2) == 0) {
3,031✔
259
    pos += 2;
595✔
260
  }
261

262
  for (; *pos != '\0'; pos++) {
484,952,164✔
263
    if (*pos == TD_DIRSEP[0]) {
475,807,008✔
264
      *pos = '\0';
66,424,566✔
265
#ifdef WINDOWS
266
      code = _mkdir(temp, mode);
267
#elif defined(DARWIN)
268
      code = mkdir(temp, 0777);
269
#else
270
      code = mkdir(temp, mode);
66,425,543✔
271
#endif
272
      if (code < 0 && ERRNO != EEXIST) {
66,426,763✔
273
        terrno = TAOS_SYSTEM_ERROR(ERRNO);
200✔
274
        return terrno;
200✔
275
      }
276
      *pos = TD_DIRSEP[0];
66,428,150✔
277
    }
278
  }
279

280
  if (*(pos - 1) != TD_DIRSEP[0]) {
9,137,830✔
281
#ifdef WINDOWS
282
    code = _mkdir(temp, mode);
283
#elif defined(DARWIN)
284
    code = mkdir(dirname, 0777);
285
#else
286
    code = mkdir(temp, mode);
8,806,954✔
287
#endif
288
    if (code < 0 && ERRNO != EEXIST) {
8,806,954✔
289
      terrno = TAOS_SYSTEM_ERROR(ERRNO);
42✔
290
      return terrno;
42✔
291
    }
292
  }
293

294
  if (code < 0 && ERRNO == EEXIST) {
9,138,201✔
295
    if (checkAccess &&
5,603,968✔
296
        taosCheckAccessFile(temp, TD_FILE_ACCESS_EXIST_OK | TD_FILE_ACCESS_READ_OK | TD_FILE_ACCESS_WRITE_OK)) {
×
297
      return 0;
×
298
    }
299
  }
300
#ifndef TD_ASTRA  // TD_ASTRA_TODO  IMPORTANT
301
  code = chmod(temp, mode);
9,138,201✔
302
  if (-1 == code) {
9,137,224✔
303
    terrno = TAOS_SYSTEM_ERROR(ERRNO);
90✔
304
    return terrno;
×
305
  }
306
#else
307
  code = 0;
308
#endif
309
  return code;
9,137,134✔
310
}
311

312
void taosRemoveOldFiles(const char *dirname, int32_t keepDays) {
825✔
313
  TdDirPtr pDir = taosOpenDir(dirname);
825✔
314
  if (pDir == NULL) return;
825✔
315

316
  int64_t       sec = taosGetTimestampSec();
625✔
317
  TdDirEntryPtr de = NULL;
625✔
318

319
  while ((de = taosReadDir(pDir)) != NULL) {
4,183✔
320
    if (strcmp(taosGetDirEntryName(de), ".") == 0 || strcmp(taosGetDirEntryName(de), "..") == 0) continue;
4,574✔
321

322
    char filename[1024];
892✔
323
    (void)snprintf(filename, sizeof(filename), "%s%s%s", dirname, TD_DIRSEP, taosGetDirEntryName(de));
2,308✔
324
    if (taosDirEntryIsDir(de)) {
2,308✔
325
      continue;
200✔
326
    } else {
327
      int32_t len = (int32_t)strlen(filename);
2,108✔
328
      if (len > 3 && strcmp(filename + len - 3, ".gz") == 0) {
2,108✔
329
        len -= 3;
600✔
330
      } else {
331
        continue;
1,508✔
332
      }
333

334
      int64_t fileSec = 0;
600✔
335
      for (int32_t i = len - 1; i >= 0; i--) {
5,000✔
336
        if (filename[i] == '.') {
5,000✔
337
          fileSec = atoll(filename + i + 1);
600✔
338
          break;
600✔
339
        }
340
      }
341

342
      if (fileSec <= 100) continue;
600✔
343
      int32_t days = (int32_t)(TABS(sec - fileSec) / 86400 + 1);
400✔
344
      if (days > keepDays) {
400✔
345
        TAOS_UNUSED(taosRemoveFile(filename));
200✔
346
        // printf("file:%s is removed, days:%d keepDays:%d, sed:%" PRId64, filename, days, keepDays, fileSec);
347
      } else {
348
        // printf("file:%s won't be removed, days:%d keepDays:%d", filename, days, keepDays);
349
      }
350
    }
351
  }
352

353
  TAOS_UNUSED(taosCloseDir(&pDir));
625✔
354
  TAOS_UNUSED(rmdir(dirname));
625✔
355
}
356

357
int32_t taosExpandDir(const char *dirname, char *outname, int32_t maxlen) {
42,878,243✔
358
  OS_PARAM_CHECK(dirname);
42,878,243✔
359
  OS_PARAM_CHECK(outname);
42,878,043✔
360
  if (dirname[0] == 0) return 0;
42,877,843✔
361

362
#ifndef TD_ASTRA
363
  wordexp_t full_path = {0};
41,559,428✔
364
  int32_t   code = wordexp(dirname, &full_path, 0);
41,559,428✔
365
  switch (code) {
41,559,428✔
366
    case 0:
41,559,428✔
367
      break;
41,559,428✔
368
    case WRDE_NOSPACE:
×
369
      wordfree(&full_path);
×
370
      // FALL THROUGH
371
    default:
×
372
      return terrno = TSDB_CODE_INVALID_PARA;
×
373
  }
374

375
  if (full_path.we_wordv != NULL && full_path.we_wordv[0] != NULL) {
41,559,428✔
376
    tstrncpy(outname, full_path.we_wordv[0], maxlen);
41,559,428✔
377
  }
378

379
  wordfree(&full_path);
41,559,428✔
380
#else // TD_ASTRA_TODO
381
  tstrncpy(outname, dirname, maxlen);
382
#endif
383
  return 0;
41,559,428✔
384
}
385

386
int32_t taosRealPath(char *dirname, char *realPath, int32_t maxlen) {
15,413,243✔
387
  OS_PARAM_CHECK(dirname);
15,413,243✔
388

389
#ifndef TD_ASTRA
390
  char tmp[PATH_MAX + 1] = {0};
15,413,043✔
391
#ifdef WINDOWS
392
  if (_fullpath(tmp, dirname, maxlen) != NULL) {
393
#else
394
  if (realpath(dirname, tmp) != NULL) {
15,411,686✔
395
#endif
396
    if (strlen(tmp) < maxlen) {
5,476,403✔
397
      if (realPath == NULL) {
5,476,203✔
398
        tstrncpy(dirname, tmp, maxlen);
4,651,324✔
399
      } else {
400
        tstrncpy(realPath, tmp, maxlen);
824,879✔
401
      }
402
      return 0;
5,474,914✔
403
    } else {
404
      terrno = TSDB_CODE_OUT_OF_MEMORY;
200✔
405
      return terrno;
200✔
406
    }
407
  } else {
408
    terrno = TAOS_SYSTEM_ERROR(ERRNO);
9,935,967✔
409
    return terrno;
9,937,665✔
410
  }
411
#else  // TD_ASTRA_TODO
412
  if (realPath) tstrncpy(realPath, dirname, maxlen);
413
  return 0;
414
#endif
415
}
416

417
bool taosIsDir(const char *dirname) {
256,976,571✔
418
  TdDirPtr pDir = taosOpenDir(dirname);
256,976,571✔
419
  if (pDir != NULL) {
256,977,215✔
420
    TAOS_SKIP_ERROR(taosCloseDir(&pDir));
23,018,225✔
421
    return true;
23,018,225✔
422
  }
423
  return false;
233,958,990✔
424
}
425

426
char *taosDirName(char *name) {
2,109,353✔
427
  if (name == NULL) {
2,109,353✔
428
    terrno = TSDB_CODE_INVALID_PARA;
200✔
429
    return NULL;
200✔
430
  }
431
#ifdef WINDOWS
432
  char Drive1[MAX_PATH], Dir1[MAX_PATH];
433
  _splitpath(name, Drive1, Dir1, NULL, NULL);
434
  size_t dirNameLen = strlen(Drive1) + strlen(Dir1);
435
  if (dirNameLen > 0) {
436
    if (name[dirNameLen - 1] == '/' || name[dirNameLen - 1] == '\\') {
437
      name[dirNameLen - 1] = 0;
438
    } else {
439
      name[dirNameLen] = 0;
440
    }
441
  } else {
442
    name[0] = 0;
443
  }
444
  return name;
445
#else
446
  char *end = strrchr(name, '/');
2,109,153✔
447
  if (end != NULL) {
2,109,153✔
448
    *end = '\0';
2,108,753✔
449
  } else {
450
    name[0] = 0;
400✔
451
  }
452
  return name;
2,109,153✔
453
#endif
454
}
455

456
char *taosDirEntryBaseName(char *name) {
2,147,483,647✔
457
  if (name == NULL) {
2,147,483,647✔
458
    terrno = TSDB_CODE_INVALID_PARA;
200✔
459
    return NULL;
200✔
460
  }
461
#ifdef WINDOWS
462
  char Filename1[MAX_PATH], Ext1[MAX_PATH];
463
  _splitpath(name, NULL, NULL, Filename1, Ext1);
464
  return name + (strlen(name) - strlen(Filename1) - strlen(Ext1));
465
#else
466
  if ((name[0] == '/' && name[1] == '\0')) return name;
2,147,483,647✔
467
  char *pPoint = strrchr(name, '/');
2,147,483,647✔
468
  if (pPoint != NULL) {
2,147,483,647✔
469
    if (*(pPoint + 1) == '\0') {
4,064✔
470
      *pPoint = '\0';
200✔
471
      return taosDirEntryBaseName(name);
200✔
472
    }
473
    return pPoint + 1;
3,864✔
474
  }
475
  return name;
2,147,483,647✔
476
#endif
477
}
478

479
TdDirPtr taosOpenDir(const char *dirname) {
446,851,581✔
480
  if (dirname == NULL) {
446,851,581✔
481
    terrno = TSDB_CODE_INVALID_PARA;
200✔
482
    return NULL;
200✔
483
  }
484

485
#ifdef WINDOWS
486
  char   szFind[MAX_PATH];  // 这是要找的
487
  HANDLE hFind;
488

489
  TdDirPtr pDir = taosMemoryMalloc(sizeof(TdDir));
490
  if (pDir == NULL) {
491
    return NULL;
492
  }
493

494
  snprintf(szFind, sizeof(szFind), "%s%s", dirname, "\\*.*");  // 利用通配符找这个目录下的所以文件,包括目录
495

496
  pDir->hFind = FindFirstFile(szFind, &(pDir->dirEntry.findFileData));
497
  if (INVALID_HANDLE_VALUE == pDir->hFind) {
498
    taosMemoryFree(pDir);
499
    DWORD errorCode = GetLastError();
500
    terrno = TAOS_SYSTEM_WINAPI_ERROR(errorCode);
501
    return NULL;
502
  }
503
  return pDir;
504
#elif defined(DARWIN)
505
  DIR *pDir = opendir(dirname);
506
  if (pDir == NULL) return NULL;
507
  TdDirPtr dirPtr = (TdDirPtr)taosMemoryMalloc(sizeof(TdDir));
508
  if (dirPtr == NULL) {
509
    (void)closedir(pDir);
510
    terrno = TAOS_SYSTEM_ERROR(ERRNO);
511
    return NULL;
512
  }
513
  dirPtr->dirEntryPtr = (TdDirEntryPtr) & (dirPtr->dirEntry1);
514
  dirPtr->pDir = pDir;
515
  return dirPtr;
516
#else
517
  TdDirPtr ptr = (TdDirPtr)opendir(dirname);
446,851,381✔
518
  if (NULL == ptr) {
446,877,612✔
519
    terrno = TAOS_SYSTEM_ERROR(ERRNO);
234,145,480✔
520
  }
521
  return ptr;
446,881,290✔
522
#endif
523
}
524

525
TdDirEntryPtr taosReadDir(TdDirPtr pDir) {
2,147,483,647✔
526
  if (pDir == NULL) {
2,147,483,647✔
527
    terrno = TSDB_CODE_INVALID_PARA;
600✔
528
    return NULL;
600✔
529
  }
530
#ifdef WINDOWS
531
  if (!FindNextFile(pDir->hFind, &(pDir->dirEntry.findFileData))) {
532
    return NULL;
533
  }
534
  return (TdDirEntryPtr) & (pDir->dirEntry.findFileData);
535
#elif defined(DARWIN)
536
  if (readdir_r(pDir->pDir, (dirent *)&(pDir->dirEntry), (dirent **)&(pDir->dirEntryPtr)) == 0) {
537
    return pDir->dirEntryPtr;
538
  } else {
539
    return NULL;
540
  }
541
#else
542
  SET_ERRNO(0);
2,147,483,647✔
543
  terrno = 0;
2,147,483,647✔
544
  TdDirEntryPtr p = (TdDirEntryPtr)readdir((DIR *)pDir);
2,147,483,647✔
545
  if (NULL == p && ERRNO) {
2,147,483,647✔
546
    terrno = TAOS_SYSTEM_ERROR(ERRNO);
×
547
  }
548
  return p;
2,147,483,647✔
549
#endif
550
}
551

552
bool taosDirEntryIsDir(TdDirEntryPtr pDirEntry) {
56,798,180✔
553
  if (pDirEntry == NULL) {
56,798,180✔
554
    return false;
400✔
555
  }
556
#ifdef WINDOWS
557
  if (pDirEntry->findFileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
558
    return false;
559
  }
560
  return (pDirEntry->findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
561
#elif defined(TD_ASTRA)  // TD_ASTRA_TODO
562
  return ((dirent *)pDirEntry)->d_mode == 1;  // DIRECTORY_ENTRY;
563
#else
564
  return (((dirent *)pDirEntry)->d_type & DT_DIR) != 0;
56,797,780✔
565
#endif
566
}
567

568
char *taosGetDirEntryName(TdDirEntryPtr pDirEntry) {
2,147,483,647✔
569
  if (pDirEntry == NULL) {
2,147,483,647✔
570
    return NULL;
200✔
571
  }
572
#ifdef WINDOWS
573
  return pDirEntry->findFileData.cFileName;
574
#else
575
  return ((dirent *)pDirEntry)->d_name;
2,147,483,647✔
576
#endif
577
}
578

579
int32_t taosCloseDir(TdDirPtr *ppDir) {
212,741,981✔
580
  int32_t code = 0;
212,741,981✔
581
  if (ppDir == NULL || *ppDir == NULL) {
212,741,981✔
582
    terrno = TSDB_CODE_INVALID_PARA;
5,465✔
583
    return terrno;
400✔
584
  }
585
#ifdef WINDOWS
586
  if (!FindClose((*ppDir)->hFind)) {
587
    terrno = TAOS_SYSTEM_WINAPI_ERROR(GetLastError());
588
    return terrno;
589
  }
590
  taosMemoryFree(*ppDir);
591
  *ppDir = NULL;
592
  return 0;
593
#elif defined(DARWIN)
594
  code = closedir((*ppDir)->pDir);
595
  if (-1 == code) {
596
    terrno = TAOS_SYSTEM_ERROR(ERRNO);
597
    return terrno;
598
  }
599
  taosMemoryFree(*ppDir);
600
  *ppDir = NULL;
601
  return 0;
602
#else
603
  code = closedir((DIR *)*ppDir);
212,738,955✔
604
  *ppDir = NULL;
212,744,423✔
605
  if (-1 == code) {
212,725,030✔
606
    terrno = TAOS_SYSTEM_ERROR(ERRNO);
×
607
    return terrno;
×
608
  }
609
  return 0;
212,725,030✔
610
#endif
611
}
612

613
void taosGetCwd(char *buf, int32_t len) {
651,455✔
614
#if !defined(WINDOWS)
615
  char *unused __attribute__((unused));
616
  unused = getcwd(buf, len - 1);
651,455✔
617
#else
618
  tstrncpy(buf, "not implemented on windows", len);
619
#endif
620
}
651,455✔
621

622
int32_t taosAppPath(char *path, int32_t maxLen) {
1,386,212✔
623
  int32_t ret = 0;
1,386,212✔
624

625
#ifdef WINDOWS
626
  ret = GetModuleFileName(NULL, path, maxLen - 1);
627
#elif defined(DARWIN)
628
  ret = _NSGetExecutablePath(path, &maxLen) ;
629
#else
630
  ret = readlink("/proc/self/exe", path, maxLen - 1);
1,386,212✔
631
#endif
632

633
  if (ret >= 0) {
1,386,212✔
634
    ret = (taosDirName(path) == NULL) ? -1 : 0;
1,386,212✔
635
  }
636

637
  return ret;
1,386,212✔
638
}
639

640
int32_t taosGetDirSize(const char *path, int64_t *size) {
47,337,114✔
641
  int32_t code = 0;
47,337,114✔
642
  char    fullPath[PATH_MAX + 100] = {0};
47,337,114✔
643

644
  TdDirPtr pDir = taosOpenDir(path);
47,337,114✔
645
  if (pDir == NULL) {
47,337,114✔
646
    return code = terrno;
200✔
647
  }
648

649
  int64_t       totalSize = 0;
47,336,914✔
650
  TdDirEntryPtr de = NULL;
47,336,914✔
651
  while ((de = taosReadDir(pDir)) != NULL) {
388,002,224✔
652
    char *name = taosGetDirEntryName(de);
340,664,988✔
653
    if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0) {
340,664,827✔
654
      continue;
94,673,506✔
655
    }
656
    (void)snprintf(fullPath, sizeof(fullPath), "%s%s%s", path, TD_DIRSEP, name);
245,991,321✔
657

658
    int64_t subSize = 0;
245,991,321✔
659
    if (taosIsDir(fullPath)) {
245,990,838✔
660
      code = taosGetDirSize(fullPath, &subSize);
15,779,038✔
661
    } else {
662
      code = taosStatFile(fullPath, &subSize, NULL, NULL);
230,212,283✔
663
    }
664

665
    if (code != 0) goto _OVER;
245,991,321✔
666
    
667
    totalSize += subSize;
245,991,321✔
668
    fullPath[0] = 0;
245,991,321✔
669
  }
670

671
_OVER:
47,336,592✔
672
  *size = totalSize;
47,336,914✔
673
  TAOS_UNUSED(taosCloseDir(&pDir));
47,336,914✔
674
  return code;
47,336,914✔
675
}
676

677

678
void* taosLoadDll(const char* fileName) {
1,386,212✔
679
#if defined(WINDOWS)
680
  void* handle = LoadLibraryA(fileName);
681
#else
682
  void* handle = dlopen(fileName, RTLD_LAZY);
1,386,212✔
683
#endif
684

685
  if (handle == NULL) {
1,386,212✔
686
    if (errno != 0) {
200✔
687
      terrno = TAOS_SYSTEM_ERROR(errno);
200✔
688
    } else {
689
      terrno = TSDB_CODE_DLL_NOT_LOAD;
×
690
    }
691
  }
692

693
  return handle;
1,386,212✔
694
}
695

696
void taosCloseDll(void* handle) {
400✔
697
  if (handle == NULL) return;
400✔
698

699
#if defined(WINDOWS)
700
  FreeLibrary((HMODULE)handle);
701
#else
702
  if (dlclose(handle) != 0 && errno != 0) {
200✔
703
      terrno = TAOS_SYSTEM_ERROR(errno);
×
704
  }
705
#endif
706
}
707

708
void* taosLoadDllFunc(void* handle, const char* funcName) {
213,415,648✔
709
  if (handle == NULL) return NULL;
213,415,648✔
710

711
#if defined(WINDOWS)
712
  void *fptr = GetProcAddress((HMODULE)handle, funcName);
713
#else
714
  void *fptr = dlsym(handle, funcName);
213,415,448✔
715
#endif
716

717
  if (handle == NULL) {
213,415,448✔
718
    if (errno != 0) {
×
719
      terrno = TAOS_SYSTEM_ERROR(errno);
×
720
    } else {
721
      terrno = TSDB_CODE_DLL_FUNC_NOT_LOAD;
×
722
    }
723
  }
724

725
  return fptr;
213,415,448✔
726
}
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