Asterisk - The Open Source Telephony Project GIT-master-0bf3178
Data Structures | Macros | Functions
io.c File Reference

I/O Management (Derived from Cheops-NG) More...

#include "asterisk.h"
#include <termios.h>
#include <sys/ioctl.h>
#include "asterisk/io.h"
#include "asterisk/utils.h"
Include dependency graph for io.c:

Go to the source code of this file.

Data Structures

struct  io_context
 Global IO variables are now in a struct in order to be made threadsafe. More...
 
struct  io_rec
 Kept for each file descriptor. More...
 

Macros

#define DEBUG(a)
 
#define GROW_SHRINK_SIZE   512
 

Functions

int ast_get_termcols (int fd)
 Columns of Terminal. More...
 
int ast_hide_password (int fd)
 Hide password. More...
 
int * ast_io_add (struct io_context *ioc, int fd, ast_io_cb callback, short events, void *data)
 Add a new I/O entry for this file descriptor with the given event mask, to call callback with data as an argument. More...
 
int * ast_io_change (struct io_context *ioc, int *id, int fd, ast_io_cb callback, short events, void *data)
 Changes an IO handler. More...
 
void ast_io_dump (struct io_context *ioc)
 Dumps the IO array. More...
 
int ast_io_remove (struct io_context *ioc, int *_id)
 Removes an IO context. More...
 
int ast_io_wait (struct io_context *ioc, int howlong)
 Make the poll call, and call the callbacks for anything that needs to be handled. More...
 
int ast_restore_tty (int fd, int oldstate)
 Restores TTY mode. More...
 
int ast_sd_get_fd (int type, const struct ast_sockaddr *addr)
 Find a listening file descriptor provided by socket activation. More...
 
int ast_sd_get_fd_un (int type, const char *path)
 Find a listening AF_LOCAL file descriptor provided by socket activation. More...
 
int ast_sd_notify (const char *state)
 a wrapper for sd_notify(): notify systemd of any state changes. More...
 
struct io_contextio_context_create (void)
 Create an I/O context. More...
 
void io_context_destroy (struct io_context *ioc)
 Destroys a context. More...
 
static int io_grow (struct io_context *ioc)
 Grow the size of our arrays. More...
 
static int io_shrink (struct io_context *ioc)
 

Detailed Description

I/O Management (Derived from Cheops-NG)

Author
Mark Spencer marks.nosp@m.ter@.nosp@m.digiu.nosp@m.m.co.nosp@m.m

Definition in file io.c.

Macro Definition Documentation

◆ DEBUG

#define DEBUG (   a)

Definition at line 48 of file io.c.

◆ GROW_SHRINK_SIZE

#define GROW_SHRINK_SIZE   512

Definition at line 67 of file io.c.

Function Documentation

◆ ast_get_termcols()

int ast_get_termcols ( int  fd)

Columns of Terminal.

Parameters
fdFalls back to 80 if the underlying ioctl fails.

Definition at line 373 of file io.c.

374{
375 struct winsize win;
376 int cols = 0;
377
378 if (!isatty(fd))
379 return -1;
380
381 if ( ioctl(fd, TIOCGWINSZ, &win) != -1 ) {
382 if ( !cols && win.ws_col > 0 )
383 cols = (int) win.ws_col;
384 } else {
385 /* assume 80 characters if the ioctl fails for some reason */
386 cols = 80;
387 }
388
389 return cols;
390}
int isatty(int)

References isatty().

Referenced by ast_cli_display_match_list().

◆ ast_hide_password()

int ast_hide_password ( int  fd)

Hide password.

Parameters
fdSet fd into non-echoing mode (if fd is a tty)

Definition at line 337 of file io.c.

338{
339 struct termios tios;
340 int res;
341 int old;
342 if (!isatty(fd))
343 return -1;
344 res = tcgetattr(fd, &tios);
345 if (res < 0)
346 return -1;
347 old = tios.c_lflag & (ECHO | ECHONL);
348 tios.c_lflag &= ~ECHO;
349 tios.c_lflag |= ECHONL;
350 res = tcsetattr(fd, TCSAFLUSH, &tios);
351 if (res < 0)
352 return -1;
353 return old;
354}
#define ECHO
Definition: ast_expr2f.c:554

References ECHO, and isatty().

Referenced by pw_cb().

◆ ast_io_add()

int * ast_io_add ( struct io_context ioc,
int  fd,
ast_io_cb  callback,
short  events,
void *  data 
)

Add a new I/O entry for this file descriptor with the given event mask, to call callback with data as an argument.

Adds an IO context.

Definition at line 162 of file io.c.

163{
164 int *ret;
165
166 DEBUG(ast_debug(1, "ast_io_add()\n"));
167
168 if (ioc->fdcnt >= ioc->maxfdcnt) {
169 /*
170 * We don't have enough space for this entry. We need to
171 * reallocate maxfdcnt poll fd's and io_rec's, or back out now.
172 */
173 if (io_grow(ioc))
174 return NULL;
175 }
176
177 /*
178 * At this point, we've got sufficiently large arrays going
179 * and we can make an entry for it in the pollfd and io_r
180 * structures.
181 */
182 ioc->fds[ioc->fdcnt].fd = fd;
183 ioc->fds[ioc->fdcnt].events = events;
184 ioc->fds[ioc->fdcnt].revents = 0;
185 ioc->ior[ioc->fdcnt].callback = callback;
186 ioc->ior[ioc->fdcnt].data = data;
187
188 if (!(ioc->ior[ioc->fdcnt].id = ast_malloc(sizeof(*ioc->ior[ioc->fdcnt].id)))) {
189 /* Bonk if we couldn't allocate an int */
190 return NULL;
191 }
192
193 *(ioc->ior[ioc->fdcnt].id) = ioc->fdcnt;
194 ret = ioc->ior[ioc->fdcnt].id;
195 ioc->fdcnt++;
196
197 return ret;
198}
static const struct adsi_event events[]
Definition: app_adsiprog.c:85
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:191
#define ast_debug(level,...)
Log a DEBUG message.
#define DEBUG(a)
Definition: io.c:48
static int io_grow(struct io_context *ioc)
Grow the size of our arrays.
Definition: io.c:123
#define NULL
Definition: resample.c:96
unsigned int fdcnt
Definition: io.c:74
struct io_rec * ior
Definition: io.c:73
struct pollfd * fds
Definition: io.c:72
unsigned int maxfdcnt
Definition: io.c:75
void * data
Definition: io.c:56
int * id
Definition: io.c:57
ast_io_cb callback
Definition: io.c:55

References ast_debug, ast_malloc, io_rec::callback, io_rec::data, DEBUG, events, io_context::fdcnt, io_context::fds, io_rec::id, io_grow(), io_context::ior, io_context::maxfdcnt, and NULL.

Referenced by ast_netsock_bindaddr(), ast_udptl_new_with_bindaddr(), do_monitor(), mbl_load_adapter(), and network_thread().

◆ ast_io_change()

int * ast_io_change ( struct io_context ioc,
int *  id,
int  fd,
ast_io_cb  callback,
short  events,
void *  data 
)

Changes an IO handler.

Parameters
iocwhich context to use
id
fdthe fd you wish it to contain now
callbacknew callback function
eventsevent mask to wait for
datadata to pass to the callback function Change an I/O handler, updating fd if > -1, callback if non-null, and revents if > -1, and data if non-null.
Returns
a pointer to the ID of the IO event
Return values
NULLon failure

Definition at line 200 of file io.c.

201{
202 /* If this id exceeds our file descriptor count it doesn't exist here */
203 if (*id > ioc->fdcnt)
204 return NULL;
205
206 if (fd > -1)
207 ioc->fds[*id].fd = fd;
208 if (callback)
209 ioc->ior[*id].callback = callback;
210 if (events)
211 ioc->fds[*id].events = events;
212 if (data)
213 ioc->ior[*id].data = data;
214
215 return id;
216}
enum queue_result id
Definition: app_queue.c:1667

References io_rec::callback, io_rec::data, events, io_context::fdcnt, io_context::fds, id, io_context::ior, and NULL.

◆ ast_io_dump()

void ast_io_dump ( struct io_context ioc)

Dumps the IO array.

Parameters
iocDebugging: Dump everything in the I/O array

Definition at line 312 of file io.c.

313{
314 /*
315 * Print some debugging information via
316 * the logger interface
317 */
318 int x;
319
320 ast_debug(1, "Asterisk IO Dump: %u entries, %u max entries\n", ioc->fdcnt, ioc->maxfdcnt);
321 ast_debug(1, "================================================\n");
322 ast_debug(1, "| ID FD Callback Data Events |\n");
323 ast_debug(1, "+------+------+-----------+-----------+--------+\n");
324 for (x = 0; x < ioc->fdcnt; x++) {
325 ast_debug(1, "| %.4d | %.4d | %p | %p | %.6x |\n",
326 *ioc->ior[x].id,
327 ioc->fds[x].fd,
328 ioc->ior[x].callback,
329 ioc->ior[x].data,
330 (unsigned)ioc->fds[x].events);
331 }
332 ast_debug(1, "================================================\n");
333}

References ast_debug, io_rec::callback, io_rec::data, io_context::fdcnt, io_context::fds, io_rec::id, io_context::ior, and io_context::maxfdcnt.

◆ ast_io_remove()

int ast_io_remove ( struct io_context ioc,
int *  id 
)

Removes an IO context.

Parameters
iocwhich io_context to remove it from
idwhich ID to remove Remove an I/O id from consideration
Return values
0on success
-1on failure

Definition at line 245 of file io.c.

246{
247 int x;
248
249 if (!_id) {
250 ast_log(LOG_WARNING, "Asked to remove NULL?\n");
251 return -1;
252 }
253
254 for (x = 0; x < ioc->fdcnt; x++) {
255 if (ioc->ior[x].id == _id) {
256 /* Free the int immediately and set to NULL so we know it's unused now */
257 ast_free(ioc->ior[x].id);
258 ioc->ior[x].id = NULL;
259 ioc->fds[x].events = 0;
260 ioc->fds[x].revents = 0;
261 ioc->needshrink = 1;
262 if (ioc->current_ioc == -1)
263 io_shrink(ioc);
264 return 0;
265 }
266 }
267
268 ast_log(LOG_NOTICE, "Unable to remove unknown id %p\n", _id);
269
270 return -1;
271}
#define ast_free(a)
Definition: astmm.h:180
#define ast_log
Definition: astobj2.c:42
#define LOG_NOTICE
#define LOG_WARNING
static int io_shrink(struct io_context *ioc)
Definition: io.c:218
int current_ioc
Definition: io.c:76
int needshrink
Definition: io.c:77

References ast_free, ast_log, io_context::current_ioc, io_context::fdcnt, io_context::fds, io_rec::id, io_shrink(), io_context::ior, LOG_NOTICE, LOG_WARNING, io_context::needshrink, and NULL.

Referenced by ast_io_wait(), ast_netsock_destroy(), ast_udptl_destroy(), mbl_load_adapter(), and network_thread().

◆ ast_io_wait()

int ast_io_wait ( struct io_context ioc,
int  howlong 
)

Make the poll call, and call the callbacks for anything that needs to be handled.

Waits for IO.

Definition at line 278 of file io.c.

279{
280 int res, x, origcnt;
281
282 DEBUG(ast_debug(1, "ast_io_wait()\n"));
283
284 if ((res = ast_poll(ioc->fds, ioc->fdcnt, howlong)) <= 0) {
285 return res;
286 }
287
288 /* At least one event tripped */
289 origcnt = ioc->fdcnt;
290 for (x = 0; x < origcnt; x++) {
291 /* Yes, it is possible for an entry to be deleted and still have an
292 event waiting if it occurs after the original calling id */
293 if (ioc->fds[x].revents && ioc->ior[x].id) {
294 /* There's an event waiting */
295 ioc->current_ioc = *ioc->ior[x].id;
296 if (ioc->ior[x].callback) {
297 if (!ioc->ior[x].callback(ioc->ior[x].id, ioc->fds[x].fd, ioc->fds[x].revents, ioc->ior[x].data)) {
298 /* Time to delete them since they returned a 0 */
299 ast_io_remove(ioc, ioc->ior[x].id);
300 }
301 }
302 ioc->current_ioc = -1;
303 }
304 }
305
306 if (ioc->needshrink)
307 io_shrink(ioc);
308
309 return res;
310}
int ast_io_remove(struct io_context *ioc, int *_id)
Removes an IO context.
Definition: io.c:245
#define ast_poll(a, b, c)
Definition: poll-compat.h:88

References ast_debug, ast_io_remove(), ast_poll, io_rec::callback, io_context::current_ioc, io_rec::data, DEBUG, io_context::fdcnt, io_context::fds, io_rec::id, io_shrink(), io_context::ior, and io_context::needshrink.

Referenced by do_monitor(), do_sco_listen(), and network_thread().

◆ ast_restore_tty()

int ast_restore_tty ( int  fd,
int  oldstatus 
)

Restores TTY mode.

Parameters
fd,oldstatusCall with result from previous ast_hide_password

Definition at line 356 of file io.c.

357{
358 int res;
359 struct termios tios;
360 if (oldstate < 0)
361 return 0;
362 res = tcgetattr(fd, &tios);
363 if (res < 0)
364 return -1;
365 tios.c_lflag &= ~(ECHO | ECHONL);
366 tios.c_lflag |= oldstate;
367 res = tcsetattr(fd, TCSAFLUSH, &tios);
368 if (res < 0)
369 return -1;
370 return 0;
371}

References ECHO.

Referenced by pw_cb().

◆ ast_sd_get_fd()

int ast_sd_get_fd ( int  type,
const struct ast_sockaddr addr 
)

Find a listening file descriptor provided by socket activation.

Parameters
typeSOCK_STREAM or SOCK_DGRAM
addrThe socket address of the bound listener.
Return values
negativeNo match.
positiveFile Descriptor matching sockaddr.
Note
This function returns -1 if systemd's development headers were not detected on the system.

Definition at line 438 of file io.c.

439{
440#ifdef HAVE_SYSTEMD
441 int count = sd_listen_fds(0);
442 int idx;
443
444 for (idx = 0; idx < count; idx++) {
445 if (!ast_sd_is_socket_sockaddr(idx + SD_LISTEN_FDS_START, type, addr)) {
446 return idx + SD_LISTEN_FDS_START;
447 }
448 }
449#endif
450
451 return -1;
452}
static const char type[]
Definition: chan_ooh323.c:109

References type.

Referenced by ast_tcptls_server_start().

◆ ast_sd_get_fd_un()

int ast_sd_get_fd_un ( int  type,
const char *  path 
)

Find a listening AF_LOCAL file descriptor provided by socket activation.

Parameters
typeSOCK_STREAM or SOCK_DGRAM
pathThe path of the listener.
Return values
negativeNo match.
positiveFile Descriptor matching path.
Note
This function returns -1 if systemd's development headers were not detected on the system.

Definition at line 454 of file io.c.

455{
456#ifdef HAVE_SYSTEMD
457 int count = sd_listen_fds(0);
458 int idx;
459
460 for (idx = 0; idx < count; idx++) {
461 if (sd_is_socket_unix(idx + SD_LISTEN_FDS_START, type, 1, path, 0) > 0) {
462 return idx + SD_LISTEN_FDS_START;
463 }
464 }
465#endif
466
467 return -1;
468}

References type.

Referenced by ast_makesocket(), and main().

◆ ast_sd_notify()

int ast_sd_notify ( const char *  state)

a wrapper for sd_notify(): notify systemd of any state changes.

Parameters
statea string that states the changes. See sd_notify(3). The wrapper does nothing if systemd ('s development headers) was not detected on the system.
Return values
0on success.
positieon success.
negativeon error.

Definition at line 392 of file io.c.

392 {
393#ifdef HAVE_SYSTEMD
394 return sd_notify(0, state);
395#else
396 return 0;
397#endif
398}

Referenced by ast_module_reload(), asterisk_daemon(), and really_quit().

◆ io_context_create()

struct io_context * io_context_create ( void  )

Create an I/O context.

Creates a context Create a context for I/O operations Basically mallocs an IO structure and sets up some default values.

Definition at line 81 of file io.c.

82{
83 struct io_context *tmp = NULL;
84
85 if (!(tmp = ast_malloc(sizeof(*tmp))))
86 return NULL;
87
88 tmp->needshrink = 0;
89 tmp->fdcnt = 0;
90 tmp->maxfdcnt = GROW_SHRINK_SIZE/2;
91 tmp->current_ioc = -1;
92
93 if (!(tmp->fds = ast_calloc(1, (GROW_SHRINK_SIZE / 2) * sizeof(*tmp->fds)))) {
95 tmp = NULL;
96 } else {
97 if (!(tmp->ior = ast_calloc(1, (GROW_SHRINK_SIZE / 2) * sizeof(*tmp->ior)))) {
98 ast_free(tmp->fds);
100 tmp = NULL;
101 }
102 }
103
104 return tmp;
105}
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
static int tmp()
Definition: bt_open.c:389
#define GROW_SHRINK_SIZE
Definition: io.c:67
Global IO variables are now in a struct in order to be made threadsafe.
Definition: io.c:71

References ast_calloc, ast_free, ast_malloc, GROW_SHRINK_SIZE, NULL, and tmp().

Referenced by load_module(), and mbl_load_adapter().

◆ io_context_destroy()

void io_context_destroy ( struct io_context ioc)

Destroys a context.

Parameters
iocstructure to destroy Destroy a context for I/O operations Frees all memory associated with the given io_context structure along with the structure itself

Definition at line 107 of file io.c.

108{
109 /* Free associated memory with an I/O context */
110 if (ioc->fds)
111 ast_free(ioc->fds);
112 if (ioc->ior)
113 ast_free(ioc->ior);
114
115 ast_free(ioc);
116}

References ast_free, io_context::fds, and io_context::ior.

Referenced by load_module(), mbl_load_adapter(), and unload_module().

◆ io_grow()

static int io_grow ( struct io_context ioc)
static

Grow the size of our arrays.

Return values
0on success
-1on failure

Definition at line 123 of file io.c.

124{
125 void *tmp;
126
127 DEBUG(ast_debug(1, "io_grow()\n"));
128
130
131 if ((tmp = ast_realloc(ioc->ior, (ioc->maxfdcnt + 1) * sizeof(*ioc->ior)))) {
132 ioc->ior = tmp;
133 if ((tmp = ast_realloc(ioc->fds, (ioc->maxfdcnt + 1) * sizeof(*ioc->fds)))) {
134 ioc->fds = tmp;
135 } else {
136 /*
137 * Failed to allocate enough memory for the pollfd. Not
138 * really any need to shrink back the iorec's as we'll
139 * probably want to grow them again soon when more memory
140 * is available, and then they'll already be the right size
141 */
143 return -1;
144 }
145 } else {
146 /*
147 * Memory allocation failure. We return to the old size, and
148 * return a failure
149 */
151 return -1;
152 }
153
154 return 0;
155}
#define ast_realloc(p, len)
A wrapper for realloc()
Definition: astmm.h:226

References ast_debug, ast_realloc, DEBUG, io_context::fds, GROW_SHRINK_SIZE, io_context::ior, io_context::maxfdcnt, and tmp().

Referenced by ast_io_add().

◆ io_shrink()

static int io_shrink ( struct io_context ioc)
static

Definition at line 218 of file io.c.

219{
220 int getfrom, putto = 0;
221
222 /*
223 * Bring the fields from the very last entry to cover over
224 * the entry we are removing, then decrease the size of the
225 * arrays by one.
226 */
227 for (getfrom = 0; getfrom < ioc->fdcnt; getfrom++) {
228 if (ioc->ior[getfrom].id) {
229 /* In use, save it */
230 if (getfrom != putto) {
231 ioc->fds[putto] = ioc->fds[getfrom];
232 ioc->ior[putto] = ioc->ior[getfrom];
233 *(ioc->ior[putto].id) = putto;
234 }
235 putto++;
236 }
237 }
238 ioc->fdcnt = putto;
239 ioc->needshrink = 0;
240 /* FIXME: We should free some memory if we have lots of unused
241 io structs */
242 return 0;
243}

References io_context::fdcnt, io_context::fds, io_rec::id, io_context::ior, and io_context::needshrink.

Referenced by ast_io_remove(), and ast_io_wait().