summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/app_ices.c4
-rw-r--r--channels/chan_phone.c4
-rw-r--r--channels/chan_sip.c9
-rw-r--r--channels/vgrabbers.c8
-rw-r--r--codecs/codec_dahdi.c7
-rw-r--r--include/asterisk/astdb.h10
-rw-r--r--include/asterisk/utils.h40
-rw-r--r--main/alertpipe.c13
-rw-r--r--main/asterisk.c4
-rw-r--r--main/db.c121
-rw-r--r--main/http.c4
-rw-r--r--main/loader.c43
-rw-r--r--main/manager.c4
-rw-r--r--main/tcptls.c13
-rw-r--r--main/udptl.c4
-rw-r--r--main/utils.c34
-rw-r--r--res/res_agi.c16
-rw-r--r--res/res_http_websocket.c24
-rw-r--r--res/res_musiconhold.c7
-rw-r--r--res/res_pjsip/pjsip_cli.c24
-rw-r--r--res/res_pktccops.c5
-rw-r--r--res/res_rtp_asterisk.c3
-rw-r--r--res/res_sorcery_astdb.c6
-rw-r--r--res/res_speech.c2
-rw-r--r--res/res_stasis.c4
-rw-r--r--res/res_timing_pthread.c4
26 files changed, 248 insertions, 169 deletions
diff --git a/apps/app_ices.c b/apps/app_ices.c
index d0fdf5cf1..a043d3de4 100644
--- a/apps/app_ices.c
+++ b/apps/app_ices.c
@@ -115,7 +115,6 @@ static int ices_exec(struct ast_channel *chan, const char *data)
int fds[2];
int ms = -1;
int pid = -1;
- int flags;
struct ast_format *oreadformat;
struct ast_frame *f;
char filename[256]="";
@@ -130,8 +129,7 @@ static int ices_exec(struct ast_channel *chan, const char *data)
ast_log(LOG_WARNING, "Unable to create pipe\n");
return -1;
}
- flags = fcntl(fds[1], F_GETFL);
- fcntl(fds[1], F_SETFL, flags | O_NONBLOCK);
+ ast_fd_set_flags(fds[1], O_NONBLOCK);
ast_stopstream(chan);
diff --git a/channels/chan_phone.c b/channels/chan_phone.c
index b418b282b..67b1e1242 100644
--- a/channels/chan_phone.c
+++ b/channels/chan_phone.c
@@ -1193,7 +1193,6 @@ static struct phone_pvt *mkif(const char *iface, int mode, int txgain, int rxgai
{
/* Make a phone_pvt structure for this interface */
struct phone_pvt *tmp;
- int flags;
tmp = ast_calloc(1, sizeof(*tmp));
if (tmp) {
@@ -1226,8 +1225,7 @@ static struct phone_pvt *mkif(const char *iface, int mode, int txgain, int rxgai
ioctl(tmp->fd, PHONE_VAD, tmp->silencesupression);
#endif
tmp->mode = mode;
- flags = fcntl(tmp->fd, F_GETFL);
- fcntl(tmp->fd, F_SETFL, flags | O_NONBLOCK);
+ ast_fd_set_flags(tmp->fd, O_NONBLOCK);
tmp->owner = NULL;
ao2_cleanup(tmp->lastformat);
tmp->lastformat = NULL;
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index 559e5c05b..b8cc7bf76 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -2948,14 +2948,7 @@ static void *_sip_tcp_helper_thread(struct ast_tcptls_session_instance *tcptls_s
goto cleanup;
}
- if ((flags = fcntl(tcptls_session->fd, F_GETFL)) == -1) {
- ast_log(LOG_ERROR, "error setting socket to non blocking mode, fcntl() failed: %s\n", strerror(errno));
- goto cleanup;
- }
-
- flags |= O_NONBLOCK;
- if (fcntl(tcptls_session->fd, F_SETFL, flags) == -1) {
- ast_log(LOG_ERROR, "error setting socket to non blocking mode, fcntl() failed: %s\n", strerror(errno));
+ if (ast_fd_set_flags(tcptls_session->fd, O_NONBLOCK)) {
goto cleanup;
}
diff --git a/channels/vgrabbers.c b/channels/vgrabbers.c
index 45dced4e1..3deb32fd1 100644
--- a/channels/vgrabbers.c
+++ b/channels/vgrabbers.c
@@ -227,12 +227,8 @@ static void *grab_v4l1_open(const char *dev, struct fbuf_t *geom, int fps)
v->b = *geom;
b = &v->b; /* shorthand */
- i = fcntl(fd, F_GETFL);
- if (-1 == fcntl(fd, F_SETFL, i | O_NONBLOCK)) {
- /* non fatal, just emit a warning */
- ast_log(LOG_WARNING, "error F_SETFL for %s [%s]\n",
- dev, strerror(errno));
- }
+ ast_fd_set_flags(fd, O_NONBLOCK);
+
/* set format for the camera.
* In principle we could retry with a different format if the
* one we are asking for is not supported.
diff --git a/codecs/codec_dahdi.c b/codecs/codec_dahdi.c
index f207b6486..edf5038ca 100644
--- a/codecs/codec_dahdi.c
+++ b/codecs/codec_dahdi.c
@@ -615,7 +615,6 @@ static int dahdi_translate(struct ast_trans_pvt *pvt, uint32_t dst_dahdi_fmt, ui
/* Request translation through zap if possible */
int fd;
struct codec_dahdi_pvt *dahdip = pvt->pvt;
- int flags;
int tried_once = 0;
const char *dev_filename = "/dev/dahdi/transcode";
@@ -661,11 +660,7 @@ retry:
return -1;
}
- flags = fcntl(fd, F_GETFL);
- if (flags > - 1) {
- if (fcntl(fd, F_SETFL, flags | O_NONBLOCK))
- ast_log(LOG_WARNING, "Could not set non-block mode!\n");
- }
+ ast_fd_set_flags(fd, O_NONBLOCK);
dahdip->fd = fd;
diff --git a/include/asterisk/astdb.h b/include/asterisk/astdb.h
index 8a870ae83..383864baf 100644
--- a/include/asterisk/astdb.h
+++ b/include/asterisk/astdb.h
@@ -83,6 +83,16 @@ int ast_db_deltree(const char *family, const char *keytree);
*/
struct ast_db_entry *ast_db_gettree(const char *family, const char *keytree);
+/*!
+ * \brief Get a list of values with the given key prefix
+ *
+ * \param family The family to search under
+ * \param key_prefix The key prefix to search under
+ *
+ * \retval NULL An error occurred
+ */
+struct ast_db_entry *ast_db_gettree_by_prefix(const char *family, const char *key_prefix);
+
/*! \brief Free structure created by ast_db_gettree() */
void ast_db_freetree(struct ast_db_entry *entry);
diff --git a/include/asterisk/utils.h b/include/asterisk/utils.h
index 03705b321..876e53c29 100644
--- a/include/asterisk/utils.h
+++ b/include/asterisk/utils.h
@@ -1142,4 +1142,44 @@ int ast_compare_versions(const char *version1, const char *version2);
*/
int ast_check_ipv6(void);
+enum ast_fd_flag_operation {
+ AST_FD_FLAG_SET,
+ AST_FD_FLAG_CLEAR,
+};
+
+/*
+ * \brief Set flags on the given file descriptor
+ * \since 13.19
+ *
+ * If getting or setting flags of the given file descriptor fails, logs an
+ * error message.
+ *
+ * \param fd File descriptor to set flags on
+ * \param flags The flag(s) to set
+ *
+ * \return -1 on error
+ * \return 0 if successful
+ */
+#define ast_fd_set_flags(fd, flags) \
+ __ast_fd_set_flags((fd), (flags), AST_FD_FLAG_SET, __FILE__, __LINE__, __PRETTY_FUNCTION__)
+
+/*
+ * \brief Clear flags on the given file descriptor
+ * \since 13.19
+ *
+ * If getting or setting flags of the given file descriptor fails, logs an
+ * error message.
+ *
+ * \param fd File descriptor to clear flags on
+ * \param flags The flag(s) to clear
+ *
+ * \return -1 on error
+ * \return 0 if successful
+ */
+#define ast_fd_clear_flags(fd, flags) \
+ __ast_fd_set_flags((fd), (flags), AST_FD_FLAG_CLEAR, __FILE__, __LINE__, __PRETTY_FUNCTION__)
+
+int __ast_fd_set_flags(int fd, int flags, enum ast_fd_flag_operation op,
+ const char *file, int lineno, const char *function);
+
#endif /* _ASTERISK_UTILS_H */
diff --git a/main/alertpipe.c b/main/alertpipe.c
index fa6ec7bcc..7932a7346 100644
--- a/main/alertpipe.c
+++ b/main/alertpipe.c
@@ -55,17 +55,8 @@ int ast_alertpipe_init(int alert_pipe[2])
ast_log(LOG_WARNING, "Failed to create alert pipe: %s\n", strerror(errno));
return -1;
} else {
- int flags = fcntl(alert_pipe[0], F_GETFL);
- if (fcntl(alert_pipe[0], F_SETFL, flags | O_NONBLOCK) < 0) {
- ast_log(LOG_WARNING, "Failed to set non-blocking mode on alert pipe: %s\n",
- strerror(errno));
- ast_alertpipe_close(alert_pipe);
- return -1;
- }
- flags = fcntl(alert_pipe[1], F_GETFL);
- if (fcntl(alert_pipe[1], F_SETFL, flags | O_NONBLOCK) < 0) {
- ast_log(LOG_WARNING, "Failed to set non-blocking mode on alert pipe: %s\n",
- strerror(errno));
+ if (ast_fd_set_flags(alert_pipe[0], O_NONBLOCK)
+ || ast_fd_set_flags(alert_pipe[1], O_NONBLOCK)) {
ast_alertpipe_close(alert_pipe);
return -1;
}
diff --git a/main/asterisk.c b/main/asterisk.c
index 0026b36d7..7edf66f34 100644
--- a/main/asterisk.c
+++ b/main/asterisk.c
@@ -1691,7 +1691,6 @@ static void *listener(void *unused)
int s;
socklen_t len;
int x;
- int flags;
struct pollfd fds[1];
for (;;) {
if (ast_socket < 0)
@@ -1729,8 +1728,7 @@ static void *listener(void *unused)
close(s);
break;
}
- flags = fcntl(consoles[x].p[1], F_GETFL);
- fcntl(consoles[x].p[1], F_SETFL, flags | O_NONBLOCK);
+ ast_fd_set_flags(consoles[x].p[1], O_NONBLOCK);
consoles[x].mute = 1; /* Default is muted, we will un-mute if necessary */
/* Default uid and gid to -2, so then in cli.c/cli_has_permissions() we will be able
to know if the user didn't send the credentials. */
diff --git a/main/db.c b/main/db.c
index ab5f7a07c..1edbcacbf 100644
--- a/main/db.c
+++ b/main/db.c
@@ -129,6 +129,20 @@ DEFINE_SQL_STATEMENT(gettree_all_stmt, "SELECT key, value FROM astdb ORDER BY ke
DEFINE_SQL_STATEMENT(showkey_stmt, "SELECT key, value FROM astdb WHERE key LIKE '%' || '/' || ? ORDER BY key")
DEFINE_SQL_STATEMENT(create_astdb_stmt, "CREATE TABLE IF NOT EXISTS astdb(key VARCHAR(256), value VARCHAR(256), PRIMARY KEY(key))")
+/* This query begs an explanation:
+ *
+ * First, the parameter binding syntax used here is slightly different then the other
+ * queries in that we use a numbered parameter so that we can bind once and get the same
+ * value substituted multiple times within the executed query.
+ *
+ * Second, the key comparison is being used to find all keys that are lexicographically
+ * greater than the provided key, but less than the provided key with a high (but
+ * invalid) Unicode codepoint appended to it. This will give us all keys in the database
+ * that have 'key' as a prefix and performs much better than the equivalent "LIKE key ||
+ * '%'" operation.
+ */
+DEFINE_SQL_STATEMENT(gettree_prefix_stmt, "SELECT key, value FROM astdb WHERE key > ?1 AND key <= ?1 || X'ffff'")
+
static int init_stmt(sqlite3_stmt **stmt, const char *sql, size_t len)
{
ast_mutex_lock(&dblock);
@@ -169,6 +183,7 @@ static void clean_statements(void)
clean_stmt(&deltree_all_stmt, deltree_all_stmt_sql);
clean_stmt(&gettree_stmt, gettree_stmt_sql);
clean_stmt(&gettree_all_stmt, gettree_all_stmt_sql);
+ clean_stmt(&gettree_prefix_stmt, gettree_prefix_stmt_sql);
clean_stmt(&showkey_stmt, showkey_stmt_sql);
clean_stmt(&put_stmt, put_stmt_sql);
clean_stmt(&create_astdb_stmt, create_astdb_stmt_sql);
@@ -184,6 +199,7 @@ static int init_statements(void)
|| init_stmt(&deltree_all_stmt, deltree_all_stmt_sql, sizeof(deltree_all_stmt_sql))
|| init_stmt(&gettree_stmt, gettree_stmt_sql, sizeof(gettree_stmt_sql))
|| init_stmt(&gettree_all_stmt, gettree_all_stmt_sql, sizeof(gettree_all_stmt_sql))
+ || init_stmt(&gettree_prefix_stmt, gettree_prefix_stmt_sql, sizeof(gettree_prefix_stmt_sql))
|| init_stmt(&showkey_stmt, showkey_stmt_sql, sizeof(showkey_stmt_sql))
|| init_stmt(&put_stmt, put_stmt_sql, sizeof(put_stmt_sql));
}
@@ -475,19 +491,64 @@ int ast_db_deltree(const char *family, const char *keytree)
return res;
}
+static struct ast_db_entry *db_gettree_common(sqlite3_stmt *stmt)
+{
+ struct ast_db_entry *head = NULL, *prev = NULL, *cur;
+
+ while (sqlite3_step(stmt) == SQLITE_ROW) {
+ const char *key, *value;
+ size_t key_len, value_len;
+
+ key = (const char *) sqlite3_column_text(stmt, 0);
+ value = (const char *) sqlite3_column_text(stmt, 1);
+
+ if (!key || !value) {
+ break;
+ }
+
+ key_len = strlen(key);
+ value_len = strlen(value);
+
+ cur = ast_malloc(sizeof(*cur) + key_len + value_len + 2);
+ if (!cur) {
+ break;
+ }
+
+ cur->next = NULL;
+ cur->key = cur->data + value_len + 1;
+ memcpy(cur->data, value, value_len + 1);
+ memcpy(cur->key, key, key_len + 1);
+
+ if (prev) {
+ prev->next = cur;
+ } else {
+ head = cur;
+ }
+ prev = cur;
+ }
+
+ return head;
+}
+
struct ast_db_entry *ast_db_gettree(const char *family, const char *keytree)
{
char prefix[MAX_DB_FIELD];
sqlite3_stmt *stmt = gettree_stmt;
- struct ast_db_entry *cur, *last = NULL, *ret = NULL;
+ size_t res = 0;
+ struct ast_db_entry *ret;
if (!ast_strlen_zero(family)) {
if (!ast_strlen_zero(keytree)) {
/* Family and key tree */
- snprintf(prefix, sizeof(prefix), "/%s/%s", family, keytree);
+ res = snprintf(prefix, sizeof(prefix), "/%s/%s", family, keytree);
} else {
/* Family only */
- snprintf(prefix, sizeof(prefix), "/%s", family);
+ res = snprintf(prefix, sizeof(prefix), "/%s", family);
+ }
+
+ if (res >= sizeof(prefix)) {
+ ast_log(LOG_WARNING, "Requested prefix is too long: %s\n", keytree);
+ return NULL;
}
} else {
prefix[0] = '\0';
@@ -495,41 +556,47 @@ struct ast_db_entry *ast_db_gettree(const char *family, const char *keytree)
}
ast_mutex_lock(&dblock);
- if (!ast_strlen_zero(prefix) && (sqlite3_bind_text(stmt, 1, prefix, -1, SQLITE_STATIC) != SQLITE_OK)) {
- ast_log(LOG_WARNING, "Could bind %s to stmt: %s\n", prefix, sqlite3_errmsg(astdb));
+ if (res && (sqlite3_bind_text(stmt, 1, prefix, res, SQLITE_STATIC) != SQLITE_OK)) {
+ ast_log(LOG_WARNING, "Could not bind %s to stmt: %s\n", prefix, sqlite3_errmsg(astdb));
sqlite3_reset(stmt);
ast_mutex_unlock(&dblock);
return NULL;
}
- while (sqlite3_step(stmt) == SQLITE_ROW) {
- const char *key_s, *value_s;
- if (!(key_s = (const char *) sqlite3_column_text(stmt, 0))) {
- break;
- }
- if (!(value_s = (const char *) sqlite3_column_text(stmt, 1))) {
- break;
- }
- if (!(cur = ast_malloc(sizeof(*cur) + strlen(key_s) + strlen(value_s) + 2))) {
- break;
- }
- cur->next = NULL;
- cur->key = cur->data + strlen(value_s) + 1;
- strcpy(cur->data, value_s);
- strcpy(cur->key, key_s);
- if (last) {
- last->next = cur;
- } else {
- ret = cur;
- }
- last = cur;
- }
+ ret = db_gettree_common(stmt);
sqlite3_reset(stmt);
ast_mutex_unlock(&dblock);
return ret;
}
+struct ast_db_entry *ast_db_gettree_by_prefix(const char *family, const char *key_prefix)
+{
+ char prefix[MAX_DB_FIELD];
+ size_t res;
+ struct ast_db_entry *ret;
+
+ res = snprintf(prefix, sizeof(prefix), "/%s/%s", family, key_prefix);
+ if (res >= sizeof(prefix)) {
+ ast_log(LOG_WARNING, "Requested key prefix is too long: %s\n", key_prefix);
+ return NULL;
+ }
+
+ ast_mutex_lock(&dblock);
+ if (sqlite3_bind_text(gettree_prefix_stmt, 1, prefix, res, SQLITE_STATIC) != SQLITE_OK) {
+ ast_log(LOG_WARNING, "Could not bind %s to stmt: %s\n", prefix, sqlite3_errmsg(astdb));
+ sqlite3_reset(gettree_prefix_stmt);
+ ast_mutex_unlock(&dblock);
+ return NULL;
+ }
+
+ ret = db_gettree_common(gettree_prefix_stmt);
+ sqlite3_reset(gettree_prefix_stmt);
+ ast_mutex_unlock(&dblock);
+
+ return ret;
+}
+
void ast_db_freetree(struct ast_db_entry *dbe)
{
struct ast_db_entry *last;
diff --git a/main/http.c b/main/http.c
index d1a443a4f..e8d395b15 100644
--- a/main/http.c
+++ b/main/http.c
@@ -1955,9 +1955,7 @@ static void *httpd_helper_thread(void *data)
}
/* make sure socket is non-blocking */
- flags = fcntl(ser->fd, F_GETFL);
- flags |= O_NONBLOCK;
- fcntl(ser->fd, F_SETFL, flags);
+ ast_fd_set_flags(ser->fd, O_NONBLOCK);
/* Setup HTTP worker private data to keep track of request body reading. */
ao2_cleanup(ser->private_data);
diff --git a/main/loader.c b/main/loader.c
index 7d792b08e..b1a02d542 100644
--- a/main/loader.c
+++ b/main/loader.c
@@ -382,35 +382,39 @@ static int verify_key(const unsigned char *key)
return -1;
}
-static int resource_name_match(const char *name1_in, const char *name2_in)
+static size_t resource_name_baselen(const char *name)
{
- char *name1 = (char *) name1_in;
- char *name2 = (char *) name2_in;
+ size_t len = strlen(name);
- /* trim off any .so extensions */
- if (!strcasecmp(name1 + strlen(name1) - 3, ".so")) {
- name1 = ast_strdupa(name1);
- name1[strlen(name1) - 3] = '\0';
+ if (len > 3 && !strcasecmp(name + len - 3, ".so")) {
+ return len - 3;
}
- if (!strcasecmp(name2 + strlen(name2) - 3, ".so")) {
- name2 = ast_strdupa(name2);
- name2[strlen(name2) - 3] = '\0';
+
+ return len;
+}
+
+static int resource_name_match(const char *name1, size_t baselen1, const char *name2)
+{
+ if (baselen1 != resource_name_baselen(name2)) {
+ return -1;
}
- return strcasecmp(name1, name2);
+ return strncasecmp(name1, name2, baselen1);
}
static struct ast_module *find_resource(const char *resource, int do_lock)
{
struct ast_module *cur;
+ size_t resource_baselen = resource_name_baselen(resource);
if (do_lock) {
AST_DLLIST_LOCK(&module_list);
}
AST_DLLIST_TRAVERSE(&module_list, cur, entry) {
- if (!resource_name_match(resource, cur->resource))
+ if (!resource_name_match(resource, resource_baselen, cur->resource)) {
break;
+ }
}
if (do_lock) {
@@ -947,6 +951,7 @@ enum ast_module_reload_result ast_module_reload(const char *name)
struct ast_module *cur;
enum ast_module_reload_result res = AST_MODULE_RELOAD_NOT_FOUND;
int i;
+ size_t name_baselen = name ? resource_name_baselen(name) : 0;
/* If we aren't fully booted, we just pretend we reloaded but we queue this
up to run once we are booted up. */
@@ -1000,8 +1005,9 @@ enum ast_module_reload_result ast_module_reload(const char *name)
AST_DLLIST_TRAVERSE(&module_list, cur, entry) {
const struct ast_module_info *info = cur->info;
- if (name && resource_name_match(name, cur->resource))
+ if (name && resource_name_match(name, name_baselen, cur->resource)) {
continue;
+ }
if (!cur->flags.running || cur->flags.declined) {
if (res == AST_MODULE_RELOAD_NOT_FOUND) {
@@ -1195,9 +1201,10 @@ AST_LIST_HEAD_NOLOCK(load_order, load_order_entry);
static struct load_order_entry *add_to_load_order(const char *resource, struct load_order *load_order, int required)
{
struct load_order_entry *order;
+ size_t resource_baselen = resource_name_baselen(resource);
AST_LIST_TRAVERSE(load_order, order, entry) {
- if (!resource_name_match(order->resource, resource)) {
+ if (!resource_name_match(resource, resource_baselen, order->resource)) {
/* Make sure we have the proper setting for the required field
(we might have both load= and required= lines in modules.conf) */
order->required |= required;
@@ -1444,11 +1451,15 @@ int load_modules(unsigned int preload_only)
/* now scan the config for any modules we are prohibited from loading and
remove them from the load order */
for (v = ast_variable_browse(cfg, "modules"); v; v = v->next) {
- if (strcasecmp(v->name, "noload"))
+ size_t baselen;
+
+ if (strcasecmp(v->name, "noload")) {
continue;
+ }
+ baselen = resource_name_baselen(v->value);
AST_LIST_TRAVERSE_SAFE_BEGIN(&load_order, order, entry) {
- if (!resource_name_match(order->resource, v->value)) {
+ if (!resource_name_match(v->value, baselen, order->resource)) {
AST_LIST_REMOVE_CURRENT(entry);
ast_free(order->resource);
ast_free(order);
diff --git a/main/manager.c b/main/manager.c
index 5bc87d547..81052651e 100644
--- a/main/manager.c
+++ b/main/manager.c
@@ -6684,9 +6684,7 @@ static void *session_do(void *data)
}
/* make sure socket is non-blocking */
- flags = fcntl(ser->fd, F_GETFL);
- flags |= O_NONBLOCK;
- fcntl(ser->fd, F_SETFL, flags);
+ ast_fd_set_flags(ser->fd, O_NONBLOCK);
ao2_lock(session);
/* Hook to the tail of the event queue */
diff --git a/main/tcptls.c b/main/tcptls.c
index ef22094bf..3c2d6788f 100644
--- a/main/tcptls.c
+++ b/main/tcptls.c
@@ -805,7 +805,7 @@ void *ast_tcptls_server_root(void *data)
pthread_t launched;
for (;;) {
- int i, flags;
+ int i;
if (desc->periodic_fn) {
desc->periodic_fn(desc);
@@ -843,8 +843,7 @@ void *ast_tcptls_server_root(void *data)
close(fd);
continue;
}
- flags = fcntl(fd, F_GETFL);
- fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
+ ast_fd_clear_flags(fd, O_NONBLOCK);
tcptls_session->fd = fd;
tcptls_session->parent = desc;
ast_sockaddr_copy(&tcptls_session->remote_address, &addr);
@@ -1061,7 +1060,6 @@ void ast_ssl_teardown(struct ast_tls_config *cfg)
struct ast_tcptls_session_instance *ast_tcptls_client_start(struct ast_tcptls_session_instance *tcptls_session)
{
struct ast_tcptls_session_args *desc;
- int flags;
if (!(desc = tcptls_session->parent)) {
goto client_start_error;
@@ -1075,8 +1073,7 @@ struct ast_tcptls_session_instance *ast_tcptls_client_start(struct ast_tcptls_se
goto client_start_error;
}
- flags = fcntl(desc->accept_fd, F_GETFL);
- fcntl(desc->accept_fd, F_SETFL, flags & ~O_NONBLOCK);
+ ast_fd_clear_flags(desc->accept_fd, O_NONBLOCK);
if (desc->tls_cfg) {
desc->tls_cfg->enabled = 1;
@@ -1164,7 +1161,6 @@ error:
void ast_tcptls_server_start(struct ast_tcptls_session_args *desc)
{
- int flags;
int x = 1;
int tls_changed = 0;
@@ -1267,8 +1263,7 @@ void ast_tcptls_server_start(struct ast_tcptls_session_args *desc)
ast_log(LOG_ERROR, "Unable to listen for %s!\n", desc->name);
goto error;
}
- flags = fcntl(desc->accept_fd, F_GETFL);
- fcntl(desc->accept_fd, F_SETFL, flags | O_NONBLOCK);
+ ast_fd_set_flags(desc->accept_fd, O_NONBLOCK);
if (ast_pthread_create_background(&desc->master, NULL, desc->accept_fn, desc)) {
ast_log(LOG_ERROR, "Unable to launch thread for %s on %s: %s\n",
desc->name,
diff --git a/main/udptl.c b/main/udptl.c
index a568cd1ec..44e9eb9bb 100644
--- a/main/udptl.c
+++ b/main/udptl.c
@@ -1014,7 +1014,6 @@ struct ast_udptl *ast_udptl_new_with_bindaddr(struct ast_sched_context *sched, s
int x;
int startplace;
int i;
- long int flags;
RAII_VAR(struct udptl_config *, cfg, ao2_global_obj_ref(globals), ao2_cleanup);
if (!cfg || !cfg->general) {
@@ -1045,8 +1044,7 @@ struct ast_udptl *ast_udptl_new_with_bindaddr(struct ast_sched_context *sched, s
ast_log(LOG_WARNING, "Unable to allocate socket: %s\n", strerror(errno));
return NULL;
}
- flags = fcntl(udptl->fd, F_GETFL);
- fcntl(udptl->fd, F_SETFL, flags | O_NONBLOCK);
+ ast_fd_set_flags(udptl->fd, O_NONBLOCK);
#ifdef SO_NO_CHECK
if (cfg->general->nochecksums)
diff --git a/main/utils.c b/main/utils.c
index 034203046..0b8dc7aeb 100644
--- a/main/utils.c
+++ b/main/utils.c
@@ -2798,3 +2798,37 @@ int ast_compare_versions(const char *version1, const char *version2)
}
return extra[0] - extra[1];
}
+
+int __ast_fd_set_flags(int fd, int flags, enum ast_fd_flag_operation op,
+ const char *file, int lineno, const char *function)
+{
+ int f;
+
+ f = fcntl(fd, F_GETFL);
+ if (f == -1) {
+ ast_log(__LOG_ERROR, file, lineno, function,
+ "Failed to get fcntl() flags for file descriptor: %s\n", strerror(errno));
+ return -1;
+ }
+
+ switch (op) {
+ case AST_FD_FLAG_SET:
+ f |= flags;
+ break;
+ case AST_FD_FLAG_CLEAR:
+ f &= ~flags;
+ break;
+ default:
+ ast_assert(0);
+ break;
+ }
+
+ f = fcntl(fd, F_SETFL, f);
+ if (f == -1) {
+ ast_log(__LOG_ERROR, file, lineno, function,
+ "Failed to set fcntl() flags for file descriptor: %s\n", strerror(errno));
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/res/res_agi.c b/res/res_agi.c
index 4caa13bb1..f19303f4d 100644
--- a/res/res_agi.c
+++ b/res/res_agi.c
@@ -2048,7 +2048,7 @@ static int handle_connection(const char *agiurl, const struct ast_sockaddr addr,
FastAGI defaults to port 4573 */
static enum agi_result launch_netscript(char *agiurl, char *argv[], int *fds)
{
- int s = 0, flags;
+ int s = 0;
char *host, *script;
int num_addrs = 0, i = 0;
struct ast_sockaddr *addrs;
@@ -2078,14 +2078,7 @@ static enum agi_result launch_netscript(char *agiurl, char *argv[], int *fds)
continue;
}
- if ((flags = fcntl(s, F_GETFL)) < 0) {
- ast_log(LOG_WARNING, "fcntl(F_GETFL) failed: %s\n", strerror(errno));
- close(s);
- continue;
- }
-
- if (fcntl(s, F_SETFL, flags | O_NONBLOCK) < 0) {
- ast_log(LOG_WARNING, "fnctl(F_SETFL) failed: %s\n", strerror(errno));
+ if (ast_fd_set_flags(s, O_NONBLOCK)) {
close(s);
continue;
}
@@ -2251,9 +2244,8 @@ static enum agi_result launch_script(struct ast_channel *chan, char *script, int
close(toast[1]);
return AGI_RESULT_FAILURE;
}
- res = fcntl(audio[1], F_GETFL);
- if (res > -1)
- res = fcntl(audio[1], F_SETFL, res | O_NONBLOCK);
+
+ res = ast_fd_set_flags(audio[1], O_NONBLOCK);
if (res < 0) {
ast_log(LOG_WARNING, "unable to set audio pipe parameters: %s\n", strerror(errno));
close(fromast[0]);
diff --git a/res/res_http_websocket.c b/res/res_http_websocket.c
index 75a6eba64..a65fc8ae2 100644
--- a/res/res_http_websocket.c
+++ b/res/res_http_websocket.c
@@ -445,19 +445,7 @@ int AST_OPTIONAL_API_NAME(ast_websocket_is_secure)(struct ast_websocket *session
int AST_OPTIONAL_API_NAME(ast_websocket_set_nonblock)(struct ast_websocket *session)
{
- int flags;
-
- if ((flags = fcntl(session->fd, F_GETFL)) == -1) {
- return -1;
- }
-
- flags |= O_NONBLOCK;
-
- if ((flags = fcntl(session->fd, F_SETFL, flags)) == -1) {
- return -1;
- }
-
- return 0;
+ return ast_fd_set_flags(session->fd, O_NONBLOCK);
}
int AST_OPTIONAL_API_NAME(ast_websocket_set_timeout)(struct ast_websocket *session, int timeout)
@@ -944,17 +932,11 @@ static struct ast_http_uri websocketuri = {
/*! \brief Simple echo implementation which echoes received text and binary frames */
static void websocket_echo_callback(struct ast_websocket *session, struct ast_variable *parameters, struct ast_variable *headers)
{
- int flags, res;
+ int res;
ast_debug(1, "Entering WebSocket echo loop\n");
- if ((flags = fcntl(ast_websocket_fd(session), F_GETFL)) == -1) {
- goto end;
- }
-
- flags |= O_NONBLOCK;
-
- if (fcntl(ast_websocket_fd(session), F_SETFL, flags) == -1) {
+ if (ast_fd_set_flags(ast_websocket_fd(session), O_NONBLOCK)) {
goto end;
}
diff --git a/res/res_musiconhold.c b/res/res_musiconhold.c
index d79151676..dee9c2da8 100644
--- a/res/res_musiconhold.c
+++ b/res/res_musiconhold.c
@@ -924,7 +924,6 @@ static struct mohclass *_get_mohbyname(const char *name, int warn, int flags, co
static struct mohdata *mohalloc(struct mohclass *cl)
{
struct mohdata *moh;
- long flags;
if (!(moh = ast_calloc(1, sizeof(*moh))))
return NULL;
@@ -936,10 +935,8 @@ static struct mohdata *mohalloc(struct mohclass *cl)
}
/* Make entirely non-blocking */
- flags = fcntl(moh->pipe[0], F_GETFL);
- fcntl(moh->pipe[0], F_SETFL, flags | O_NONBLOCK);
- flags = fcntl(moh->pipe[1], F_GETFL);
- fcntl(moh->pipe[1], F_SETFL, flags | O_NONBLOCK);
+ ast_fd_set_flags(moh->pipe[0], O_NONBLOCK);
+ ast_fd_set_flags(moh->pipe[1], O_NONBLOCK);
moh->f.frametype = AST_FRAME_VOICE;
moh->f.subclass.format = cl->format;
diff --git a/res/res_pjsip/pjsip_cli.c b/res/res_pjsip/pjsip_cli.c
index 56ec191ed..4544a1717 100644
--- a/res/res_pjsip/pjsip_cli.c
+++ b/res/res_pjsip/pjsip_cli.c
@@ -82,31 +82,22 @@ int ast_sip_cli_print_sorcery_objectset(void *obj, void *arg, int flags)
return 0;
}
-static char *complete_show_sorcery_object(struct ao2_container *container,
+static void complete_show_sorcery_object(struct ao2_container *container,
struct ast_sip_cli_formatter_entry *formatter_entry,
- const char *word, int state)
+ const char *word)
{
- char *result = NULL;
- int wordlen = strlen(word);
- int which = 0;
-
- struct ao2_iterator i = ao2_iterator_init(container, 0);
+ size_t wordlen = strlen(word);
void *object;
+ struct ao2_iterator i = ao2_iterator_init(container, 0);
while ((object = ao2_t_iterator_next(&i, "iterate thru endpoints table"))) {
const char *id = formatter_entry->get_id(object);
- if (!strncasecmp(word, id, wordlen)
- && ++which > state) {
- result = ast_strdup(id);
+ if (!strncasecmp(word, id, wordlen)) {
+ ast_cli_completion_add(ast_strdup(id));
}
ao2_t_ref(object, -1, "toss iterator endpoint ptr before break");
- if (result) {
- break;
- }
}
ao2_iterator_destroy(&i);
-
- return result;
}
static void dump_str_and_free(int fd, struct ast_str *buf)
@@ -211,7 +202,8 @@ char *ast_sip_cli_traverse_objects(struct ast_cli_entry *e, int cmd, struct ast_
if (cmd == CLI_GENERATE) {
ast_free(context.output_buffer);
- return complete_show_sorcery_object(container, formatter_entry, a->word, a->n);
+ complete_show_sorcery_object(container, formatter_entry, a->word);
+ return NULL;
}
if (is_container) {
diff --git a/res/res_pktccops.c b/res/res_pktccops.c
index 037e533d3..8a4c3a5c0 100644
--- a/res/res_pktccops.c
+++ b/res/res_pktccops.c
@@ -650,7 +650,7 @@ static struct cops_gate *cops_gate_cmd(int cmd, struct cops_cmts *cmts,
static int cops_connect(char *host, char *port)
{
- int s, sfd = -1, flags;
+ int s, sfd = -1;
struct addrinfo hints;
struct addrinfo *rp;
struct addrinfo *result;
@@ -676,8 +676,7 @@ static int cops_connect(char *host, char *port)
if (sfd == -1) {
ast_log(LOG_WARNING, "Failed socket\n");
}
- flags = fcntl(sfd, F_GETFL);
- fcntl(sfd, F_SETFL, flags | O_NONBLOCK);
+ ast_fd_set_flags(sfd, O_NONBLOCK);
#ifdef HAVE_SO_NOSIGPIPE
setsockopt(sfd, SOL_SOCKET, SO_NOSIGPIPE, &trueval, sizeof(trueval));
#endif
diff --git a/res/res_rtp_asterisk.c b/res/res_rtp_asterisk.c
index 5271d1bf4..c921f36b3 100644
--- a/res/res_rtp_asterisk.c
+++ b/res/res_rtp_asterisk.c
@@ -2765,8 +2765,7 @@ static int create_new_socket(const char *type, int af)
}
ast_log(LOG_WARNING, "Unable to allocate %s socket: %s\n", type, strerror(errno));
} else {
- long flags = fcntl(sock, F_GETFL);
- fcntl(sock, F_SETFL, flags | O_NONBLOCK);
+ ast_fd_set_flags(sock, O_NONBLOCK);
#ifdef SO_NO_CHECK
if (nochecksums) {
setsockopt(sock, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums));
diff --git a/res/res_sorcery_astdb.c b/res/res_sorcery_astdb.c
index fee857525..135709ebd 100644
--- a/res/res_sorcery_astdb.c
+++ b/res/res_sorcery_astdb.c
@@ -336,14 +336,14 @@ static void sorcery_astdb_retrieve_prefix(const struct ast_sorcery *sorcery, voi
const char *family_prefix = data;
size_t family_len = strlen(family_prefix) + strlen(type) + 1; /* +1 for slash delimiter */
char family[family_len + 1];
- char tree[prefix_len + sizeof("%")];
+ char tree[prefix_len + 1];
RAII_VAR(struct ast_db_entry *, entries, NULL, ast_db_freetree);
struct ast_db_entry *entry;
- snprintf(tree, sizeof(tree), "%.*s%%", (int) prefix_len, prefix);
+ snprintf(tree, sizeof(tree), "%.*s", (int) prefix_len, prefix);
snprintf(family, sizeof(family), "%s/%s", family_prefix, type);
- if (!(entries = ast_db_gettree(family, tree))) {
+ if (!(entries = ast_db_gettree_by_prefix(family, tree))) {
return;
}
diff --git a/res/res_speech.c b/res/res_speech.c
index 7d75985ca..f61588f57 100644
--- a/res/res_speech.c
+++ b/res/res_speech.c
@@ -365,5 +365,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_
.support_level = AST_MODULE_SUPPORT_CORE,
.load = load_module,
.unload = unload_module,
- .load_pri = AST_MODPRI_APP_DEPEND,
+ .load_pri = AST_MODPRI_APP_DEPEND - 1,
);
diff --git a/res/res_stasis.c b/res/res_stasis.c
index b1cea3ad5..9a06a5287 100644
--- a/res/res_stasis.c
+++ b/res/res_stasis.c
@@ -2124,8 +2124,8 @@ static int load_module(void)
return AST_MODULE_LOAD_SUCCESS;
}
-AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS, "Stasis application support",
- .load_pri = AST_MODPRI_APP_DEPEND,
+AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER, "Stasis application support",
+ .load_pri = AST_MODPRI_APP_DEPEND - 1,
.support_level = AST_MODULE_SUPPORT_CORE,
.load = load_module,
.unload = unload_module,
diff --git a/res/res_timing_pthread.c b/res/res_timing_pthread.c
index 1e76720ec..0654059f9 100644
--- a/res/res_timing_pthread.c
+++ b/res/res_timing_pthread.c
@@ -132,9 +132,7 @@ static void *pthread_timer_open(void)
}
for (i = 0; i < ARRAY_LEN(timer->pipe); ++i) {
- int flags = fcntl(timer->pipe[i], F_GETFL);
- flags |= O_NONBLOCK;
- fcntl(timer->pipe[i], F_SETFL, flags);
+ ast_fd_set_flags(timer->pipe[i], O_NONBLOCK);
}
ao2_lock(pthread_timers);