| 68 | #endif /* !RTE_EXEC_ENV_WINDOWS */ |
| 69 | |
| 70 | int |
| 71 | rte_telemetry_register_cmd(const char *cmd, telemetry_cb fn, const char *help) |
| 72 | { |
| 73 | struct cmd_callback *new_callbacks; |
| 74 | const char *cmdp = cmd; |
| 75 | int i = 0; |
| 76 | |
| 77 | if (strlen(cmd) >= MAX_CMD_LEN || fn == NULL || cmd[0] != '/' |
| 78 | || strlen(help) >= RTE_TEL_MAX_STRING_LEN) |
| 79 | return -EINVAL; |
| 80 | |
| 81 | while (*cmdp != '\0') { |
| 82 | if (!isalnum(*cmdp) && *cmdp != '_' && *cmdp != '/') |
| 83 | return -EINVAL; |
| 84 | cmdp++; |
| 85 | } |
| 86 | |
| 87 | rte_spinlock_lock(&callback_sl); |
| 88 | new_callbacks = realloc(callbacks, sizeof(callbacks[0]) * (num_callbacks + 1)); |
| 89 | if (new_callbacks == NULL) { |
| 90 | rte_spinlock_unlock(&callback_sl); |
| 91 | return -ENOMEM; |
| 92 | } |
| 93 | callbacks = new_callbacks; |
| 94 | |
| 95 | while (i < num_callbacks && strcmp(cmd, callbacks[i].cmd) > 0) |
| 96 | i++; |
| 97 | if (i != num_callbacks) |
| 98 | /* Move elements to keep the list alphabetical */ |
| 99 | memmove(callbacks + i + 1, callbacks + i, |
| 100 | sizeof(struct cmd_callback) * (num_callbacks - i)); |
| 101 | |
| 102 | strlcpy(callbacks[i].cmd, cmd, MAX_CMD_LEN); |
| 103 | callbacks[i].fn = fn; |
| 104 | strlcpy(callbacks[i].help, help, RTE_TEL_MAX_STRING_LEN); |
| 105 | num_callbacks++; |
| 106 | rte_spinlock_unlock(&callback_sl); |
| 107 | |
| 108 | return 0; |
| 109 | } |
| 110 | |
| 111 | #ifndef RTE_EXEC_ENV_WINDOWS |
| 112 | |