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

taosdata / TDengine / #5070

17 May 2026 01:15AM UTC coverage: 73.326% (-0.06%) from 73.389%
#5070

push

travis-ci

web-flow
feat (TDgpt): Dynamic Model Synchronization Enhancements (#35344)

* refactor: do some internal refactor.

* fix: fix multiprocess sync issue.

* feat: add dynamic anomaly detection and forecasting services

* fix: log error message for undeploying model in exception handling

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* fix: handle undeploy when model exists only on disk

Agent-Logs-Url: https://github.com/taosdata/TDengine/sessions/286aafa0-c3ce-4c27-b803-2707571e9dc1

Co-authored-by: hjxilinx <8252296+hjxilinx@users.noreply.github.com>

* fix: guard dynamic registry concurrent access

Agent-Logs-Url: https://github.com/taosdata/TDengine/sessions/5e4db858-6458-40f4-ac28-d1b1b7f97c18

Co-authored-by: hjxilinx <8252296+hjxilinx@users.noreply.github.com>

* fix: tighten service list locking scope

Agent-Logs-Url: https://github.com/taosdata/TDengine/sessions/5e4db858-6458-40f4-ac28-d1b1b7f97c18

Co-authored-by: hjxilinx <8252296+hjxilinx@users.noreply.github.com>

* fix: restore prophet support and update tests per review feedback

Agent-Logs-Url: https://github.com/taosdata/TDengine/sessions/92298ae1-7da6-4d07-b20e-101c7cd0b26b

Co-authored-by: hjxilinx <8252296+hjxilinx@users.noreply.github.com>

* fix: improve test name and move copy inside lock scope

Agent-Logs-Url: https://github.com/taosdata/TDengine/sessions/92298ae1-7da6-4d07-b20e-101c7cd0b26b

Co-authored-by: hjxilinx <8252296+hjxilinx@users.noreply.github.com>

* Potential fix for pull request finding

Co-au... (continued)

281421 of 383795 relevant lines covered (73.33%)

138892949.74 hits per line

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

43.69
/source/os/src/osSystem.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 ALLOW_FORBID_FUNC
17
#define _DEFAULT_SOURCE
18
#include "os.h"
19

20
#if defined(WINDOWS)
21
typedef void (*MainWindows)(int argc, char** argv);
22
MainWindows mainWindowsFunc = NULL;
23

24
SERVICE_STATUS        ServiceStatus;
25
SERVICE_STATUS_HANDLE hServiceStatusHandle;
26
void WINAPI           windowsServiceCtrlHandle(DWORD request) {
27
            switch (request) {
28
              case SERVICE_CONTROL_STOP:
29
              case SERVICE_CONTROL_SHUTDOWN:
30
      raise(SIGINT);
31
      ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING;
32
      if (!SetServiceStatus(hServiceStatusHandle, &ServiceStatus)) {
33
                  DWORD nError = GetLastError();
34
                  fprintf(stderr, "failed to send stopped status to windows service: %d", nError);
35
      }
36
      break;
37
              default:
38
      return;
39
  }
40
}
41
void WINAPI mainWindowsService(int argc, char** argv) {
42
  int ret = 0;
43
  ServiceStatus.dwServiceType = SERVICE_WIN32;
44
  ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_PAUSE_CONTINUE | SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
45
  ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
46
  ServiceStatus.dwWin32ExitCode = 0;
47
  ServiceStatus.dwCheckPoint = 0;
48
  ServiceStatus.dwWaitHint = 0;
49
  ServiceStatus.dwServiceSpecificExitCode = 0;
50
  hServiceStatusHandle = RegisterServiceCtrlHandler("taosd", &windowsServiceCtrlHandle);
51
  if (hServiceStatusHandle == 0) {
52
    DWORD nError = GetLastError();
53
    fprintf(stderr, "failed to register windows service ctrl handler: %d", nError);
54
  }
55

56
  ServiceStatus.dwCurrentState = SERVICE_RUNNING;
57
  if (SetServiceStatus(hServiceStatusHandle, &ServiceStatus)) {
58
    DWORD nError = GetLastError();
59
    fprintf(stderr, "failed to send running status to windows service: %d", nError);
60
  }
61
  if (mainWindowsFunc != NULL) mainWindowsFunc(argc, argv);
62
  ServiceStatus.dwCurrentState = SERVICE_STOPPED;
63
  if (!SetServiceStatus(hServiceStatusHandle, &ServiceStatus)) {
64
    DWORD nError = GetLastError();
65
    fprintf(stderr, "failed to send stopped status to windows service: %d", nError);
66
  }
67
}
68
void stratWindowsService(MainWindows mainWindows) {
69
  mainWindowsFunc = mainWindows;
70
  SERVICE_TABLE_ENTRY ServiceTable[2];
71
  ServiceTable[0].lpServiceName = "taosd";
72
  ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)mainWindowsService;
73
  ServiceTable[1].lpServiceName = NULL;
74
  ServiceTable[1].lpServiceProc = NULL;
75
  StartServiceCtrlDispatcher(ServiceTable);
76
}
77

78
#elif defined(_TD_DARWIN_64) || defined(TD_ASTRA)
79
#else
80
#include <dlfcn.h>
81
#include <termios.h>
82
#include <unistd.h>
83
#endif
84

85
#if !defined(WINDOWS) && !defined(TD_ASTRA)
86
struct termios oldtio;
87
#endif
88

89
typedef struct FILE TdCmd;
90

91
int32_t taosSetConsoleEcho(bool on) {
412✔
92
#if defined(WINDOWS)
93
  HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
94
  if (hStdin == INVALID_HANDLE_VALUE) {
95
    terrno = TAOS_SYSTEM_WINAPI_ERROR(GetLastError());
96
    return terrno;
97
  }
98
  DWORD mode = 0;
99
  if (!GetConsoleMode(hStdin, &mode)) {
100
    terrno = TAOS_SYSTEM_WINAPI_ERROR(GetLastError());
101
    return terrno;
102
  }
103
  if (on) {
104
    mode |= ENABLE_ECHO_INPUT;
105
  } else {
106
    mode &= ~ENABLE_ECHO_INPUT;
107
  }
108
  if (!SetConsoleMode(hStdin, mode)) {
109
    terrno = TAOS_SYSTEM_WINAPI_ERROR(GetLastError());
110
    return terrno;
111
  }
112

113
  return 0;
114
#elif defined(TD_ASTRA)  // TD_ASTRA_TODO
115
  return 0;
116
#else
117
#define ECHOFLAGS (ECHO | ECHOE | ECHOK | ECHONL)
118
  int            err;
119
  struct termios term;
×
120

121
  if (tcgetattr(STDIN_FILENO, &term) == -1) {
412✔
122
    terrno = TAOS_SYSTEM_ERROR(ERRNO);
412✔
123
    return terrno;
412✔
124
  }
125

126
  if (on)
×
127
    term.c_lflag |= ECHOFLAGS;
×
128
  else
129
    term.c_lflag &= ~ECHOFLAGS;
×
130

131
  err = tcsetattr(STDIN_FILENO, TCSAFLUSH, &term);
×
132
  if (err == -1) {
×
133
    terrno = TAOS_SYSTEM_ERROR(ERRNO);
×
134
    return terrno;
×
135
  }
136

137
  return 0;
×
138
#endif
139
}
140

141
int32_t taosSetTerminalMode() {
668✔
142
#if defined(WINDOWS) || defined(TD_ASTRA)  // TD_ASTRA_TODO
143
  return 0;
144
#else
145
  struct termios newtio;
668✔
146

147
  /* if (atexit() != 0) { */
148
  /*     fprintf(stderr, "Error register exit function!\n"); */
149
  /*     exit(EXIT_FAILURE); */
150
  /* } */
151

152
  (void)memcpy(&newtio, &oldtio, sizeof(oldtio));
668✔
153

154
  // Set new terminal attributes.
155
  newtio.c_iflag &= ~(IXON | IXOFF | ICRNL | INLCR | IGNCR | IMAXBEL | ISTRIP);
668✔
156
  newtio.c_iflag |= IGNBRK;
668✔
157

158
  // newtio.c_oflag &= ~(OPOST|ONLCR|OCRNL|ONLRET);
159
  newtio.c_oflag |= OPOST;
668✔
160
  newtio.c_oflag |= ONLCR;
668✔
161
  newtio.c_oflag &= ~(OCRNL | ONLRET);
668✔
162

163
  newtio.c_lflag &= ~(IEXTEN | ICANON | ECHO | ECHOE | ECHONL | ECHOCTL | ECHOPRT | ECHOKE | ISIG);
668✔
164
  newtio.c_cc[VMIN] = 1;
668✔
165
  newtio.c_cc[VTIME] = 0;
668✔
166

167
  if (-1 == tcsetattr(0, TCSANOW, &newtio)) {
668✔
168
    terrno = TAOS_SYSTEM_ERROR(ERRNO);
×
169
    (void)fprintf(stderr, "Fail to set terminal properties!\n");
×
170
    return terrno;
×
171
  }
172

173
  return 0;
668✔
174
#endif
175
}
176

177
int32_t taosGetOldTerminalMode() {
540✔
178
#if defined(WINDOWS) || defined(TD_ASTRA)  // TD_ASTRA_TODO
179
  return 0;
180
#else
181
  /* Make sure stdin is a terminal. */
182
  if (!isatty(STDIN_FILENO)) {
540✔
183
    terrno = TAOS_SYSTEM_ERROR(ERRNO);
206✔
184
    return terrno;
206✔
185
  }
186

187
  // Get the parameter of current terminal
188
  if (-1 == tcgetattr(0, &oldtio)) {
334✔
189
    terrno = TAOS_SYSTEM_ERROR(ERRNO);
×
190
    return terrno;
×
191
  }
192

193
  return 0;
334✔
194
#endif
195
}
196

197
int32_t taosResetTerminalMode() {
668✔
198
#if defined(WINDOWS) || defined(TD_ASTRA)  // TD_ASTRA_TODO
199
  return 0;
200
#else
201
  if (-1 == tcsetattr(0, TCSANOW, &oldtio)) {
668✔
202
    terrno = TAOS_SYSTEM_ERROR(ERRNO);
334✔
203
    (void)fprintf(stderr, "Fail to reset the terminal properties!\n");
334✔
204
    return terrno;
334✔
205
  }
206
#endif
207
  return 0;
334✔
208
}
209

210
// 允许的命令白名单,用于防止命令注入
211
static bool isCommandAllowed(const char* cmd) {
1,127,803✔
212
  const char* allowedCmds[] = {"taos", "taosd", "taosdump", "taosBenchmark", "taosAdapter", "taosKeeper", NULL};
1,127,803✔
213
  for (const char** p = allowedCmds; *p != NULL; p++) {
7,894,621✔
214
    size_t cmdLen = strlen(*p);
6,766,818✔
215
    if (strncmp(cmd, *p, cmdLen) == 0) {
6,766,818✔
216
      char nextChar = cmd[cmdLen];
×
217
      if (nextChar == ' ' || nextChar == '\t' || nextChar == '\0') {
×
218
        return true;
×
219
      }
220
    }
221
  }
222
  return false;
1,127,803✔
223
}
224

225
// 移除危险字符,用于防止命令注入
226
static bool sanitizeCommand(const char* cmd) {
×
227
  const char* dangerousChars = ";|&`$()<>{}[]!*?~";
×
228
  for (const char* p = dangerousChars; *p; p++) {
×
229
    if (strchr(cmd, *p) != NULL) {
×
230
      return false;
×
231
    }
232
  }
233
  return true;
×
234
}
235

236
TdCmdPtr taosOpenCmd(const char* cmd) {
1,128,009✔
237
  if (cmd == NULL) {
1,128,009✔
238
    terrno = TSDB_CODE_INVALID_PARA;
206✔
239
    return NULL;
206✔
240
  }
241

242
  if (!isCommandAllowed(cmd)) {
1,127,803✔
243
    terrno = TSDB_CODE_INVALID_PARA;
1,127,803✔
244
    return NULL;
1,127,803✔
245
  }
246

247
  if (!sanitizeCommand(cmd)) {
×
248
    terrno = TSDB_CODE_INVALID_PARA;
×
249
    return NULL;
×
250
  }
251

252
#ifdef WINDOWS
253
  return (TdCmdPtr)_popen(cmd, "r");
254
#elif defined(TD_ASTRA)
255
  return NULL;
256
#else
257
  TdCmdPtr p = (TdCmdPtr)popen(cmd, "r");
×
258
  if (NULL == p) {
×
259
    terrno = TAOS_SYSTEM_ERROR(ERRNO);
×
260
  }
261
  return p;
×
262
#endif
263
}
264

265
int64_t taosGetsCmd(TdCmdPtr pCmd, int32_t maxSize, char* __restrict buf) {
×
266
  if (pCmd == NULL || buf == NULL) {
×
267
    terrno = TSDB_CODE_INVALID_PARA;
×
268
    return terrno;
×
269
  }
270
  if (fgets(buf, maxSize, (FILE*)pCmd) == NULL) {
×
271
    if (feof((FILE*)pCmd)) {
×
272
      return 0;
×
273
    }
274

275
    terrno = TAOS_SYSTEM_ERROR(ferror((FILE*)pCmd));
×
276
    return terrno;
×
277
  }
278

279
  return strlen(buf);
×
280
}
281

282
int64_t taosGetLineCmd(TdCmdPtr pCmd, char** __restrict ptrBuf) {
×
283
  if (pCmd == NULL || ptrBuf == NULL) {
×
284
    terrno = TSDB_CODE_INVALID_PARA;
×
285
    return terrno;
×
286
  }
287
  if (*ptrBuf != NULL) {
×
288
    taosMemoryFreeClear(*ptrBuf);
×
289
  }
290

291
#ifdef WINDOWS
292
  *ptrBuf = taosMemoryMalloc(1024);
293
  if (*ptrBuf == NULL) return -1;
294
  if (fgets(*ptrBuf, 1023, (FILE*)pCmd) == NULL) {
295
    taosMemoryFreeClear(*ptrBuf);
296
    return -1;
297
  }
298
  (*ptrBuf)[1023] = 0;
299
  return strlen(*ptrBuf);
300
#elif defined(TD_ASTRA)
301
  size_t bufsize = 128;
302
  size_t pos = 0;
303
  int    c;
304
  if (*ptrBuf == NULL) {
305
    *ptrBuf = (char*)taosMemoryMalloc(bufsize);
306
    if (*ptrBuf == NULL) {
307
      return terrno;
308
    }
309
  }
310
  while ((c = fgetc((FILE*)pCmd)) != EOF) {
311
    if (pos + 1 >= bufsize) {
312
      size_t new_size = bufsize << 1;
313
      char*  new_line = (char*)taosMemoryRealloc(*ptrBuf, new_size);
314
      if (new_line == NULL) {
315
        return terrno;
316
      }
317
      *ptrBuf = new_line;
318
      bufsize = new_size;
319
    }
320
    (*ptrBuf)[pos++] = (char)c;
321
    if (c == '\n') {
322
      break;
323
    }
324
  }
325
  if (pos == 0 && c == EOF) {
326
    return TSDB_CODE_INVALID_PARA;
327
  }
328
  (*ptrBuf)[pos] = '\0';
329
  return (ssize_t)pos;
330
#else
331
  ssize_t len = 0;
×
332
  len = getline(ptrBuf, (size_t*)&len, (FILE*)pCmd);
×
333
  if (-1 == len) {
×
334
    terrno = TAOS_SYSTEM_ERROR(ERRNO);
×
335
    return terrno;
×
336
  }
337
  return len;
×
338
#endif
339
}
340

341
int32_t taosEOFCmd(TdCmdPtr pCmd) {
×
342
  if (pCmd == NULL) {
×
343
    return 0;
×
344
  }
345
  return feof((FILE*)pCmd);
×
346
}
347

348
void taosCloseCmd(TdCmdPtr* ppCmd) {
412✔
349
  if (ppCmd == NULL || *ppCmd == NULL) {
412✔
350
    return;
412✔
351
  }
352
#ifdef WINDOWS
353
  _pclose((FILE*)(*ppCmd));
354
#elif defined(TD_ASTRA)  // TD_ASTRA_TODO
355
#else
356
  (void)pclose((FILE*)(*ppCmd));
×
357
#endif
358
  *ppCmd = NULL;
×
359
}
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