mirror of
https://github.com/asterisk/asterisk.git
synced 2025-10-10 06:49:40 +00:00
utils: Add convenience function for setting fd flags
There are many places in the code base where we ignore the return value of fcntl() when getting/setting file descriptior flags. This patch introduces a convenience function that allows setting or clearing file descriptor flags and will also log an error on failure for later analysis. Change-Id: I8b81901e1b1bd537ca632567cdb408931c6eded7
This commit is contained in:
@@ -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);
|
||||
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -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.
|
||||
|
@@ -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;
|
||||
|
||||
|
@@ -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 */
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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. */
|
||||
|
@@ -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);
|
||||
|
@@ -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 */
|
||||
|
@@ -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,
|
||||
|
@@ -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)
|
||||
|
34
main/utils.c
34
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;
|
||||
}
|
||||
|
@@ -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]);
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -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;
|
||||
|
@@ -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
|
||||
|
@@ -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));
|
||||
|
@@ -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);
|
||||
|
Reference in New Issue
Block a user