|
|
|
@ -1239,14 +1239,9 @@ int ast_channel_alert_write(struct ast_channel *chan)
|
|
|
|
|
return write(chan->alertpipe[1], &blah, sizeof(blah)) != sizeof(blah);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ast_alert_status_t ast_channel_internal_alert_read(struct ast_channel *chan)
|
|
|
|
|
static int channel_internal_alert_check_nonblock(struct ast_channel *chan)
|
|
|
|
|
{
|
|
|
|
|
int flags;
|
|
|
|
|
char blah;
|
|
|
|
|
|
|
|
|
|
if (!ast_channel_internal_alert_readable(chan)) {
|
|
|
|
|
return AST_ALERT_NOT_READABLE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
flags = fcntl(chan->alertpipe[0], F_GETFL);
|
|
|
|
|
/* For some odd reason, the alertpipe occasionally loses nonblocking status,
|
|
|
|
@ -1255,9 +1250,62 @@ ast_alert_status_t ast_channel_internal_alert_read(struct ast_channel *chan)
|
|
|
|
|
ast_log(LOG_ERROR, "Alertpipe on channel %s lost O_NONBLOCK?!!\n", ast_channel_name(chan));
|
|
|
|
|
if (fcntl(chan->alertpipe[0], F_SETFL, flags | O_NONBLOCK) < 0) {
|
|
|
|
|
ast_log(LOG_WARNING, "Unable to set alertpipe nonblocking! (%d: %s)\n", errno, strerror(errno));
|
|
|
|
|
return AST_ALERT_READ_FATAL;
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ast_alert_status_t ast_channel_internal_alert_flush(struct ast_channel *chan)
|
|
|
|
|
{
|
|
|
|
|
int bytes_read;
|
|
|
|
|
char blah[100];
|
|
|
|
|
|
|
|
|
|
if (!ast_channel_internal_alert_readable(chan)) {
|
|
|
|
|
return AST_ALERT_NOT_READABLE;
|
|
|
|
|
}
|
|
|
|
|
if (channel_internal_alert_check_nonblock(chan)) {
|
|
|
|
|
return AST_ALERT_READ_FATAL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Read the alertpipe until it is exhausted. */
|
|
|
|
|
for (;;) {
|
|
|
|
|
bytes_read = read(chan->alertpipe[0], blah, sizeof(blah));
|
|
|
|
|
if (bytes_read < 0) {
|
|
|
|
|
if (errno == EINTR) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if (errno == EAGAIN || errno == EWOULDBLOCK) {
|
|
|
|
|
/*
|
|
|
|
|
* Would block so nothing left to read.
|
|
|
|
|
* This is the normal loop exit.
|
|
|
|
|
*/
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
ast_log(LOG_WARNING, "read() failed flushing alertpipe: %s\n",
|
|
|
|
|
strerror(errno));
|
|
|
|
|
return AST_ALERT_READ_FAIL;
|
|
|
|
|
}
|
|
|
|
|
if (!bytes_read) {
|
|
|
|
|
/* Read nothing so we are done */
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return AST_ALERT_READ_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ast_alert_status_t ast_channel_internal_alert_read(struct ast_channel *chan)
|
|
|
|
|
{
|
|
|
|
|
char blah;
|
|
|
|
|
|
|
|
|
|
if (!ast_channel_internal_alert_readable(chan)) {
|
|
|
|
|
return AST_ALERT_NOT_READABLE;
|
|
|
|
|
}
|
|
|
|
|
if (channel_internal_alert_check_nonblock(chan)) {
|
|
|
|
|
return AST_ALERT_READ_FATAL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (read(chan->alertpipe[0], &blah, sizeof(blah)) < 0) {
|
|
|
|
|
if (errno != EINTR && errno != EAGAIN) {
|
|
|
|
|
ast_log(LOG_WARNING, "read() failed: %s\n", strerror(errno));
|
|
|
|
|