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

taosdata / TDengine / #4720

08 Sep 2025 08:43AM UTC coverage: 58.139% (-0.6%) from 58.762%
#4720

push

travis-ci

web-flow
Merge pull request #32881 from taosdata/enh/add-new-windows-ci

fix(ci): update workflow reference to use new Windows CI YAML

133181 of 292179 branches covered (45.58%)

Branch coverage included in aggregate %.

201691 of 283811 relevant lines covered (71.07%)

5442780.71 hits per line

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

85.78
/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
void taosRemoveDir(const char *dirname) {
46,928✔
98
  TdDirPtr pDir = taosOpenDir(dirname);
46,928✔
99
  if (pDir == NULL) return;
46,928✔
100

101
  TdDirEntryPtr de = NULL;
46,614✔
102
  while ((de = taosReadDir(pDir)) != NULL) {
259,058✔
103
    if (strcmp(taosGetDirEntryName(de), ".") == 0 || strcmp(taosGetDirEntryName(de), "..") == 0) continue;
212,444✔
104

105
    char filename[1024] = {0};
119,216✔
106
    (void)snprintf(filename, sizeof(filename), "%s%s%s", dirname, TD_DIRSEP, taosGetDirEntryName(de));
119,216✔
107
    if (taosDirEntryIsDir(de)) {
119,216✔
108
      taosRemoveDir(filename);
37,378✔
109
    } else {
110
      TAOS_UNUSED(taosRemoveFile(filename));
81,838✔
111
      // printf("file:%s is removed\n", filename);
112
    }
113
  }
114

115
  TAOS_UNUSED(taosCloseDir(&pDir));
46,614✔
116
  TAOS_UNUSED(rmdir(dirname));
46,614✔
117

118
  // printf("dir:%s is removed\n", dirname);
119
  return;
46,614✔
120
}
121

122
bool taosDirExist(const char *dirname) {
219,894✔
123
  if (dirname == NULL || strlen(dirname) >= TDDIRMAXLEN) return false;
219,894!
124
  return taosCheckExistFile(dirname);
219,883✔
125
}
126

127
int32_t taosMkDir(const char *dirname) {
152,197✔
128
  if (taosDirExist(dirname)) return 0;
152,197✔
129
#ifdef WINDOWS
130
  int32_t code = _mkdir(dirname, 0755);
131
#elif defined(DARWIN)
132
  int32_t code = mkdir(dirname, 0777);
133
#else
134
  int32_t code = mkdir(dirname, 0755);
84,498✔
135
#endif
136
  if (-1 == code) {
84,497✔
137
    if (ERRNO == EEXIST) {
144✔
138
      return 0;
14✔
139
    } else {
140
      terrno = TAOS_SYSTEM_ERROR(ERRNO);
130✔
141
      code = terrno;
130✔
142
    }
143
  }
144

145
  return code;
84,484✔
146
}
147

148
int32_t taosMulMkDir(const char *dirname) {
19,427✔
149
  if (dirname == NULL || strlen(dirname) >= TDDIRMAXLEN) return -1;
19,427✔
150
  char    temp[TDDIRMAXLEN];
151
  char   *pos = temp;
19,421✔
152
  int32_t code = 0;
19,421✔
153
#ifdef WINDOWS
154
  code = taosRealPath(dirname, temp, sizeof(temp));
155
  if (code != 0) {
156
    return code;
157
  }
158
  if (temp[1] == ':') pos += 3;
159
#else
160
  tstrncpy(temp, dirname, sizeof(temp));
19,421✔
161
#endif
162

163
  if (taosDirExist(temp)) return code;
19,421✔
164

165
  if (strncmp(temp, TD_DIRSEP, 1) == 0) {
2,656✔
166
    pos += 1;
2,647✔
167
  } else if (strncmp(temp, "." TD_DIRSEP, 2) == 0) {
9✔
168
    pos += 2;
3✔
169
  }
170

171
  for (; *pos != '\0'; pos++) {
109,085✔
172
    if (*pos == TD_DIRSEP[0]) {
106,432✔
173
      *pos = '\0';
14,842✔
174
#ifdef WINDOWS
175
      code = _mkdir(temp, 0755);
176
#elif defined(DARWIN)
177
      code = mkdir(temp, 0777);
178
#else
179
      code = mkdir(temp, 0755);
14,842✔
180
#endif
181
      if (code < 0 && ERRNO != EEXIST) {
14,842✔
182
        terrno = TAOS_SYSTEM_ERROR(ERRNO);
3✔
183
        return code;
3✔
184
      }
185
      *pos = TD_DIRSEP[0];
14,839✔
186
    }
187
  }
188

189
  if (*(pos - 1) != TD_DIRSEP[0]) {
2,653!
190
#ifdef WINDOWS
191
    code = _mkdir(temp, 0755);
192
#elif defined(DARWIN)
193
    code = mkdir(dirname, 0777);
194
#else
195
    code = mkdir(temp, 0755);
2,653✔
196
#endif
197
    if (code < 0 && ERRNO != EEXIST) {
2,653!
198
      terrno = TAOS_SYSTEM_ERROR(ERRNO);
3✔
199
      return code;
3✔
200
    }
201
  }
202

203
  return 0;
2,650✔
204
}
205

206
int32_t taosMulModeMkDir(const char *dirname, int32_t mode, bool checkAccess) {
33,767✔
207
  if (dirname == NULL || strlen(dirname) >= TDDIRMAXLEN) {
33,767✔
208
    terrno = TSDB_CODE_INVALID_PARA;
7✔
209
    return terrno;
6✔
210
  }
211
  char    temp[TDDIRMAXLEN];
212
  char   *pos = temp;
33,760✔
213
  int32_t code = 0;
33,760✔
214
#ifdef WINDOWS
215
  code = taosRealPath(dirname, temp, sizeof(temp));
216
  if (code != 0) {
217
    return code;
218
  }
219
  if (temp[1] == ':') pos += 3;
220
#else
221
  tstrncpy(temp, dirname, sizeof(temp));
33,760✔
222
#endif
223

224
  if (taosDirExist(temp)) {
33,760✔
225
    if (checkAccess &&
32,844!
226
        taosCheckAccessFile(temp, TD_FILE_ACCESS_EXIST_OK | TD_FILE_ACCESS_READ_OK | TD_FILE_ACCESS_WRITE_OK)) {
8,863✔
227
      return 0;
8,863✔
228
    }
229
#ifndef TD_ASTRA  // TD_ASTRA_TODO  IMPORTANT
230
    code = chmod(temp, mode);
15,118✔
231
    if (-1 == code) {
15,107!
232
      struct stat statbuf = {0};
×
233
      code = stat(temp, &statbuf);
×
234
      if (code != 0 || (statbuf.st_mode & mode) != mode) {
×
235
        terrno = TAOS_SYSTEM_ERROR(ERRNO);
×
236
        return terrno;
×
237
      }
238
    }
239
#else
240
    return 0;
241
#endif
242
  }
243

244
  if (strncmp(temp, TD_DIRSEP, 1) == 0) {
24,893✔
245
    pos += 1;
24,848✔
246
  } else if (strncmp(temp, "." TD_DIRSEP, 2) == 0) {
45✔
247
    pos += 2;
9✔
248
  }
249

250
  for (; *pos != '\0'; pos++) {
1,342,937✔
251
    if (*pos == TD_DIRSEP[0]) {
1,318,013✔
252
      *pos = '\0';
185,225✔
253
#ifdef WINDOWS
254
      code = _mkdir(temp, mode);
255
#elif defined(DARWIN)
256
      code = mkdir(temp, 0777);
257
#else
258
      code = mkdir(temp, mode);
185,225✔
259
#endif
260
      if (code < 0 && ERRNO != EEXIST) {
185,259✔
261
        terrno = TAOS_SYSTEM_ERROR(ERRNO);
3✔
262
        return terrno;
3✔
263
      }
264
      *pos = TD_DIRSEP[0];
185,256✔
265
    }
266
  }
267

268
  if (*(pos - 1) != TD_DIRSEP[0]) {
24,924✔
269
#ifdef WINDOWS
270
    code = _mkdir(temp, mode);
271
#elif defined(DARWIN)
272
    code = mkdir(dirname, 0777);
273
#else
274
    code = mkdir(temp, mode);
24,896✔
275
#endif
276
    if (code < 0 && ERRNO != EEXIST) {
24,895✔
277
      terrno = TAOS_SYSTEM_ERROR(ERRNO);
1✔
278
      return terrno;
1✔
279
    }
280
  }
281

282
  if (code < 0 && ERRNO == EEXIST) {
24,922!
283
    if (checkAccess &&
15,115!
284
        taosCheckAccessFile(temp, TD_FILE_ACCESS_EXIST_OK | TD_FILE_ACCESS_READ_OK | TD_FILE_ACCESS_WRITE_OK)) {
×
285
      return 0;
×
286
    }
287
  }
288
#ifndef TD_ASTRA  // TD_ASTRA_TODO  IMPORTANT
289
  code = chmod(temp, mode);
24,922✔
290
  if (-1 == code) {
24,890!
291
    terrno = TAOS_SYSTEM_ERROR(ERRNO);
×
292
    return terrno;
×
293
  }
294
#else
295
  code = 0;
296
#endif
297
  return code;
24,894✔
298
}
299

300
void taosRemoveOldFiles(const char *dirname, int32_t keepDays) {
8✔
301
  TdDirPtr pDir = taosOpenDir(dirname);
8✔
302
  if (pDir == NULL) return;
8✔
303

304
  int64_t       sec = taosGetTimestampSec();
5✔
305
  TdDirEntryPtr de = NULL;
5✔
306

307
  while ((de = taosReadDir(pDir)) != NULL) {
36✔
308
    if (strcmp(taosGetDirEntryName(de), ".") == 0 || strcmp(taosGetDirEntryName(de), "..") == 0) continue;
46✔
309

310
    char filename[1024];
311
    (void)snprintf(filename, sizeof(filename), "%s%s%s", dirname, TD_DIRSEP, taosGetDirEntryName(de));
21✔
312
    if (taosDirEntryIsDir(de)) {
21✔
313
      continue;
3✔
314
    } else {
315
      int32_t len = (int32_t)strlen(filename);
18✔
316
      if (len > 3 && strcmp(filename + len - 3, ".gz") == 0) {
18!
317
        len -= 3;
9✔
318
      } else {
319
        continue;
9✔
320
      }
321

322
      int64_t fileSec = 0;
9✔
323
      for (int32_t i = len - 1; i >= 0; i--) {
75!
324
        if (filename[i] == '.') {
75✔
325
          fileSec = atoll(filename + i + 1);
9✔
326
          break;
9✔
327
        }
328
      }
329

330
      if (fileSec <= 100) continue;
9✔
331
      int32_t days = (int32_t)(TABS(sec - fileSec) / 86400 + 1);
6✔
332
      if (days > keepDays) {
6✔
333
        TAOS_UNUSED(taosRemoveFile(filename));
3✔
334
        // printf("file:%s is removed, days:%d keepDays:%d, sed:%" PRId64, filename, days, keepDays, fileSec);
335
      } else {
336
        // printf("file:%s won't be removed, days:%d keepDays:%d", filename, days, keepDays);
337
      }
338
    }
339
  }
340

341
  TAOS_UNUSED(taosCloseDir(&pDir));
5✔
342
  TAOS_UNUSED(rmdir(dirname));
5✔
343
}
344

345
int32_t taosExpandDir(const char *dirname, char *outname, int32_t maxlen) {
104,662✔
346
  OS_PARAM_CHECK(dirname);
104,662✔
347
  OS_PARAM_CHECK(outname);
104,659✔
348
  if (dirname[0] == 0) return 0;
104,656✔
349

350
#ifndef TD_ASTRA
351
  wordexp_t full_path = {0};
104,651✔
352
  int32_t   code = wordexp(dirname, &full_path, 0);
104,651✔
353
  switch (code) {
104,651!
354
    case 0:
104,651✔
355
      break;
104,651✔
356
    case WRDE_NOSPACE:
×
357
      wordfree(&full_path);
×
358
      // FALL THROUGH
359
    default:
×
360
      return terrno = TSDB_CODE_INVALID_PARA;
×
361
  }
362

363
  if (full_path.we_wordv != NULL && full_path.we_wordv[0] != NULL) {
104,651!
364
    tstrncpy(outname, full_path.we_wordv[0], maxlen);
104,651✔
365
  }
366

367
  wordfree(&full_path);
104,651✔
368
#else // TD_ASTRA_TODO
369
  tstrncpy(outname, dirname, maxlen);
370
#endif
371
  return 0;
104,651✔
372
}
373

374
int32_t taosRealPath(char *dirname, char *realPath, int32_t maxlen) {
42,101✔
375
  OS_PARAM_CHECK(dirname);
42,101✔
376

377
#ifndef TD_ASTRA
378
  char tmp[PATH_MAX + 1] = {0};
42,098✔
379
#ifdef WINDOWS
380
  if (_fullpath(tmp, dirname, maxlen) != NULL) {
381
#else
382
  if (realpath(dirname, tmp) != NULL) {
42,098✔
383
#endif
384
    if (strlen(tmp) < maxlen) {
11,260✔
385
      if (realPath == NULL) {
11,257✔
386
        tstrncpy(dirname, tmp, maxlen);
8,483✔
387
      } else {
388
        tstrncpy(realPath, tmp, maxlen);
2,774✔
389
      }
390
      return 0;
11,257✔
391
    } else {
392
      terrno = TSDB_CODE_OUT_OF_MEMORY;
3✔
393
      return terrno;
3✔
394
    }
395
  } else {
396
    terrno = TAOS_SYSTEM_ERROR(ERRNO);
30,845✔
397
    return terrno;
30,842✔
398
  }
399
#else  // TD_ASTRA_TODO
400
  if (realPath) tstrncpy(realPath, dirname, maxlen);
401
  return 0;
402
#endif
403
}
404

405
bool taosIsDir(const char *dirname) {
484,026✔
406
  TdDirPtr pDir = taosOpenDir(dirname);
484,026✔
407
  if (pDir != NULL) {
484,019✔
408
    TAOS_SKIP_ERROR(taosCloseDir(&pDir));
53,473✔
409
    return true;
53,477✔
410
  }
411
  return false;
430,546✔
412
}
413

414
char *taosDirName(char *name) {
4,706✔
415
  if (name == NULL) {
4,706✔
416
    terrno = TSDB_CODE_INVALID_PARA;
3✔
417
    return NULL;
3✔
418
  }
419
#ifdef WINDOWS
420
  char Drive1[MAX_PATH], Dir1[MAX_PATH];
421
  _splitpath(name, Drive1, Dir1, NULL, NULL);
422
  size_t dirNameLen = strlen(Drive1) + strlen(Dir1);
423
  if (dirNameLen > 0) {
424
    if (name[dirNameLen - 1] == '/' || name[dirNameLen - 1] == '\\') {
425
      name[dirNameLen - 1] = 0;
426
    } else {
427
      name[dirNameLen] = 0;
428
    }
429
  } else {
430
    name[0] = 0;
431
  }
432
  return name;
433
#else
434
  char *end = strrchr(name, '/');
4,703✔
435
  if (end != NULL) {
4,703✔
436
    *end = '\0';
4,696✔
437
  } else {
438
    name[0] = 0;
7✔
439
  }
440
  return name;
4,703✔
441
#endif
442
}
443

444
char *taosDirEntryBaseName(char *name) {
28,792,900✔
445
  if (name == NULL) {
28,792,900✔
446
    terrno = TSDB_CODE_INVALID_PARA;
3✔
447
    return NULL;
3✔
448
  }
449
#ifdef WINDOWS
450
  char Filename1[MAX_PATH], Ext1[MAX_PATH];
451
  _splitpath(name, NULL, NULL, Filename1, Ext1);
452
  return name + (strlen(name) - strlen(Filename1) - strlen(Ext1));
453
#else
454
  if ((name[0] == '/' && name[1] == '\0')) return name;
28,792,897✔
455
  char *pPoint = strrchr(name, '/');
28,792,894✔
456
  if (pPoint != NULL) {
28,792,894✔
457
    if (*(pPoint + 1) == '\0') {
15✔
458
      *pPoint = '\0';
3✔
459
      return taosDirEntryBaseName(name);
3✔
460
    }
461
    return pPoint + 1;
12✔
462
  }
463
  return name;
28,792,879✔
464
#endif
465
}
466

467
TdDirPtr taosOpenDir(const char *dirname) {
1,013,364✔
468
  if (dirname == NULL) {
1,013,364✔
469
    terrno = TSDB_CODE_INVALID_PARA;
3✔
470
    return NULL;
3✔
471
  }
472

473
#ifdef WINDOWS
474
  char   szFind[MAX_PATH];  // 这是要找的
475
  HANDLE hFind;
476

477
  TdDirPtr pDir = taosMemoryMalloc(sizeof(TdDir));
478
  if (pDir == NULL) {
479
    return NULL;
480
  }
481

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

484
  pDir->hFind = FindFirstFile(szFind, &(pDir->dirEntry.findFileData));
485
  if (INVALID_HANDLE_VALUE == pDir->hFind) {
486
    taosMemoryFree(pDir);
487
    DWORD errorCode = GetLastError();
488
    terrno = TAOS_SYSTEM_WINAPI_ERROR(errorCode);
489
    return NULL;
490
  }
491
  return pDir;
492
#elif defined(DARWIN)
493
  DIR *pDir = opendir(dirname);
494
  if (pDir == NULL) return NULL;
495
  TdDirPtr dirPtr = (TdDirPtr)taosMemoryMalloc(sizeof(TdDir));
496
  if (dirPtr == NULL) {
497
    (void)closedir(pDir);
498
    terrno = TAOS_SYSTEM_ERROR(ERRNO);
499
    return NULL;
500
  }
501
  dirPtr->dirEntryPtr = (TdDirEntryPtr) & (dirPtr->dirEntry1);
502
  dirPtr->pDir = pDir;
503
  return dirPtr;
504
#else
505
  TdDirPtr ptr = (TdDirPtr)opendir(dirname);
1,013,361✔
506
  if (NULL == ptr) {
1,013,402✔
507
    terrno = TAOS_SYSTEM_ERROR(ERRNO);
431,144✔
508
  }
509
  return ptr;
1,013,417✔
510
#endif
511
}
512

513
TdDirEntryPtr taosReadDir(TdDirPtr pDir) {
30,290,843✔
514
  if (pDir == NULL) {
30,290,843✔
515
    terrno = TSDB_CODE_INVALID_PARA;
9✔
516
    return NULL;
9✔
517
  }
518
#ifdef WINDOWS
519
  if (!FindNextFile(pDir->hFind, &(pDir->dirEntry.findFileData))) {
520
    return NULL;
521
  }
522
  return (TdDirEntryPtr) & (pDir->dirEntry.findFileData);
523
#elif defined(DARWIN)
524
  if (readdir_r(pDir->pDir, (dirent *)&(pDir->dirEntry), (dirent **)&(pDir->dirEntryPtr)) == 0) {
525
    return pDir->dirEntryPtr;
526
  } else {
527
    return NULL;
528
  }
529
#else
530
  SET_ERRNO(0);
30,290,834✔
531
  terrno = 0;
30,290,834✔
532
  TdDirEntryPtr p = (TdDirEntryPtr)readdir((DIR *)pDir);
30,229,791✔
533
  if (NULL == p && ERRNO) {
30,253,921!
534
    terrno = TAOS_SYSTEM_ERROR(ERRNO);
×
535
  }
536
  return p;
30,253,921✔
537
#endif
538
}
539

540
bool taosDirEntryIsDir(TdDirEntryPtr pDirEntry) {
164,896✔
541
  if (pDirEntry == NULL) {
164,896✔
542
    return false;
3✔
543
  }
544
#ifdef WINDOWS
545
  if (pDirEntry->findFileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
546
    return false;
547
  }
548
  return (pDirEntry->findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
549
#elif defined(TD_ASTRA)  // TD_ASTRA_TODO
550
  return ((dirent *)pDirEntry)->d_mode == 1;  // DIRECTORY_ENTRY;
551
#else
552
  return (((dirent *)pDirEntry)->d_type & DT_DIR) != 0;
164,893✔
553
#endif
554
}
555

556
char *taosGetDirEntryName(TdDirEntryPtr pDirEntry) {
30,063,648✔
557
  if (pDirEntry == NULL) {
30,063,648✔
558
    return NULL;
3✔
559
  }
560
#ifdef WINDOWS
561
  return pDirEntry->findFileData.cFileName;
562
#else
563
  return ((dirent *)pDirEntry)->d_name;
30,063,645✔
564
#endif
565
}
566

567
int32_t taosCloseDir(TdDirPtr *ppDir) {
582,120✔
568
  int32_t code = 0;
582,120✔
569
  if (ppDir == NULL || *ppDir == NULL) {
582,120!
570
    terrno = TSDB_CODE_INVALID_PARA;
×
571
    return terrno;
3✔
572
  }
573
#ifdef WINDOWS
574
  if (!FindClose((*ppDir)->hFind)) {
575
    terrno = TAOS_SYSTEM_WINAPI_ERROR(GetLastError());
576
    return terrno;
577
  }
578
  taosMemoryFree(*ppDir);
579
  *ppDir = NULL;
580
  return 0;
581
#elif defined(DARWIN)
582
  code = closedir((*ppDir)->pDir);
583
  if (-1 == code) {
584
    terrno = TAOS_SYSTEM_ERROR(ERRNO);
585
    return terrno;
586
  }
587
  taosMemoryFree(*ppDir);
588
  *ppDir = NULL;
589
  return 0;
590
#else
591
  code = closedir((DIR *)*ppDir);
582,191✔
592
  *ppDir = NULL;
582,309✔
593
  if (-1 == code) {
582,309!
594
    terrno = TAOS_SYSTEM_ERROR(ERRNO);
×
595
    return terrno;
×
596
  }
597
  return 0;
582,309✔
598
#endif
599
}
600

601
void taosGetCwd(char *buf, int32_t len) {
2,381✔
602
#if !defined(WINDOWS)
603
  char *unused __attribute__((unused));
604
  unused = getcwd(buf, len - 1);
2,381✔
605
#else
606
  tstrncpy(buf, "not implemented on windows", len);
607
#endif
608
}
2,381✔
609

610
int32_t taosAppPath(char *path, int32_t maxLen) {
2,041✔
611
  int32_t ret = 0;
2,041✔
612

613
#ifdef WINDOWS
614
  ret = GetModuleFileName(NULL, path, maxLen - 1);
615
#elif defined(DARWIN)
616
  ret = _NSGetExecutablePath(path, &maxLen) ;
617
#else
618
  ret = readlink("/proc/self/exe", path, maxLen - 1);
2,041✔
619
#endif
620

621
  if (ret >= 0) {
2,041!
622
    ret = (taosDirName(path) == NULL) ? -1 : 0;
2,041!
623
  }
624

625
  return ret;
2,041✔
626
}
627

628
int32_t taosGetDirSize(const char *path, int64_t *size) {
96,033✔
629
  int32_t code = 0;
96,033✔
630
  char    fullPath[PATH_MAX + 100] = {0};
96,033✔
631

632
  TdDirPtr pDir = taosOpenDir(path);
96,033✔
633
  if (pDir == NULL) {
96,032✔
634
    return code = terrno;
3✔
635
  }
636

637
  int64_t       totalSize = 0;
96,029✔
638
  TdDirEntryPtr de = NULL;
96,029✔
639
  while ((de = taosReadDir(pDir)) != NULL) {
743,849✔
640
    char *name = taosGetDirEntryName(de);
647,829✔
641
    if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0) {
647,829✔
642
      continue;
192,058✔
643
    }
644
    (void)snprintf(fullPath, sizeof(fullPath), "%s%s%s", path, TD_DIRSEP, name);
455,771✔
645

646
    int64_t subSize = 0;
455,771✔
647
    if (taosIsDir(fullPath)) {
455,771✔
648
      code = taosGetDirSize(fullPath, &subSize);
32,011✔
649
    } else {
650
      code = taosStatFile(fullPath, &subSize, NULL, NULL);
423,759✔
651
    }
652

653
    if (code != 0) goto _OVER;
455,767✔
654
    
655
    totalSize += subSize;
455,762✔
656
    fullPath[0] = 0;
455,762✔
657
  }
658

659
_OVER:
96,021✔
660
  *size = totalSize;
96,026✔
661
  TAOS_UNUSED(taosCloseDir(&pDir));
96,026✔
662
  return code;
96,030✔
663
}
664

665

666
void* taosLoadDll(const char* fileName) {
2,041✔
667
#if defined(WINDOWS)
668
  void* handle = LoadLibraryA(fileName);
669
#else
670
  void* handle = dlopen(fileName, RTLD_LAZY);
2,041✔
671
#endif
672

673
  if (handle == NULL) {
2,041!
674
    if (errno != 0) {
×
675
      terrno = TAOS_SYSTEM_ERROR(errno);
×
676
    } else {
677
      terrno = TSDB_CODE_DLL_NOT_LOAD;
×
678
    }
679
  }
680

681
  return handle;
2,041✔
682
}
683

684
void taosCloseDll(void* handle) {
×
685
  if (handle == NULL) return;
×
686

687
#if defined(WINDOWS)
688
  FreeLibrary((HMODULE)handle);
689
#else
690
  if (dlclose(handle) != 0 && errno != 0) {
×
691
      terrno = TAOS_SYSTEM_ERROR(errno);
×
692
  }
693
#endif
694
}
695

696
void* taosLoadDllFunc(void* handle, const char* funcName) {
293,904✔
697
  if (handle == NULL) return NULL;
293,904!
698

699
#if defined(WINDOWS)
700
  void *fptr = GetProcAddress((HMODULE)handle, funcName);
701
#else
702
  void *fptr = dlsym(handle, funcName);
293,904✔
703
#endif
704

705
  if (handle == NULL) {
293,904!
706
    if (errno != 0) {
×
707
      terrno = TAOS_SYSTEM_ERROR(errno);
×
708
    } else {
709
      terrno = TSDB_CODE_DLL_FUNC_NOT_LOAD;
×
710
    }
711
  }
712

713
  return fptr;
293,904✔
714
}
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

© 2025 Coveralls, Inc