Main Page | Alphabetical List | Data Structures | File List | Data Fields | Globals

io.c File Reference

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <termios.h>
#include <string.h>
#include <sys/ioctl.h>
#include <asterisk/io.h>
#include <asterisk/logger.h>

Include dependency graph for io.c:

Include dependency graph

Go to the source code of this file.

Data Structures

struct  io_rec
struct  io_context

Defines

#define DEBUG(a)
#define GROW_SHRINK_SIZE   512

Functions

io_contextio_context_create (void)
 Creates a context.

void io_context_destroy (struct io_context *ioc)
 Destroys a context.

int * ast_io_add (struct io_context *ioc, int fd, ast_io_cb callback, short events, void *data)
 Adds an IO context.

int * ast_io_change (struct io_context *ioc, int *id, int fd, ast_io_cb callback, short events, void *data)
 Changes an IO handler.

int ast_io_remove (struct io_context *ioc, int *_id)
 Removes an IO context.

int ast_io_wait (struct io_context *ioc, int howlong)
 Waits for IO.

void ast_io_dump (struct io_context *ioc)
 Dumps the IO array.

int ast_hide_password (int fd)
 Set fd into non-echoing mode (if fd is a tty).

int ast_restore_tty (int fd, int oldstate)
 Restores TTY mode.

int ast_get_termcols (int fd)


Define Documentation

#define DEBUG  ) 
 

Definition at line 26 of file io.c.

Referenced by ast_io_add(), ast_io_wait(), ast_sched_add(), ast_sched_del(), ast_sched_runq(), and ast_sched_wait().

#define GROW_SHRINK_SIZE   512
 

Definition at line 45 of file io.c.

Referenced by io_context_create().


Function Documentation

int ast_get_termcols int  fd  ) 
 

Definition at line 341 of file io.c.

00342 { 00343 struct winsize win; 00344 int cols = 0; 00345 00346 if (!isatty(fd)) 00347 return -1; 00348 00349 if ( ioctl(fd, TIOCGWINSZ, &win) != -1 ) { 00350 if ( !cols && win.ws_col > 0 ) 00351 cols = (int) win.ws_col; 00352 } else { 00353 /* assume 80 characters if the ioctl fails for some reason */ 00354 cols = 80; 00355 } 00356 00357 return cols; 00358 }

int ast_hide_password int  fd  ) 
 

Set fd into non-echoing mode (if fd is a tty).

Definition at line 305 of file io.c.

00306 { 00307 struct termios tios; 00308 int res; 00309 int old; 00310 if (!isatty(fd)) 00311 return -1; 00312 res = tcgetattr(fd, &tios); 00313 if (res < 0) 00314 return -1; 00315 old = tios.c_lflag & (ECHO | ECHONL); 00316 tios.c_lflag &= ~ECHO; 00317 tios.c_lflag |= ECHONL; 00318 res = tcsetattr(fd, TCSAFLUSH, &tios); 00319 if (res < 0) 00320 return -1; 00321 return old; 00322 }

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

Adds an IO context.

Parameters:
ioc which context to use
fd which fd to monitor
callback callback function to run
events event mask of events to wait for
data data to pass to the callback Watch for any of revents activites on fd, calling callback with data as callback data. Returns a pointer to ID of the IO event, or NULL on failure.

Definition at line 139 of file io.c.

References ast_io_cb, ast_log(), io_rec::callback, io_rec::data, DEBUG, pollfd::events, pollfd::fd, io_context::fdcnt, io_context::fds, io_rec::id, io_context::ior, LOG_DEBUG, malloc, and io_context::maxfdcnt.

Referenced by ast_rtp_new().

00140 { 00141 /* 00142 * Add a new I/O entry for this file descriptor 00143 * with the given event mask, to call callback with 00144 * data as an argument. Returns NULL on failure. 00145 */ 00146 int *ret; 00147 DEBUG(ast_log(LOG_DEBUG, "ast_io_add()\n")); 00148 if (ioc->fdcnt >= ioc->maxfdcnt) { 00149 /* 00150 * We don't have enough space for this entry. We need to 00151 * reallocate maxfdcnt poll fd's and io_rec's, or back out now. 00152 */ 00153 if (io_grow(ioc)) 00154 return NULL; 00155 } 00156 00157 /* 00158 * At this point, we've got sufficiently large arrays going 00159 * and we can make an entry for it in the pollfd and io_r 00160 * structures. 00161 */ 00162 ioc->fds[ioc->fdcnt].fd = fd; 00163 ioc->fds[ioc->fdcnt].events = events; 00164 ioc->ior[ioc->fdcnt].callback = callback; 00165 ioc->ior[ioc->fdcnt].data = data; 00166 ioc->ior[ioc->fdcnt].id = (int *)malloc(sizeof(int)); 00167 /* Bonk if we couldn't allocate an int */ 00168 if (!ioc->ior[ioc->fdcnt].id) 00169 return NULL; 00170 *(ioc->ior[ioc->fdcnt].id) = ioc->fdcnt; 00171 ret = ioc->ior[ioc->fdcnt].id; 00172 ioc->fdcnt++; 00173 return ret; 00174 }

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:
ioc which context to use
id 
fd the fd you wish it to contain now
callback new callback function
events event mask to wait for
data data 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 pointero to the ID of the IO event, or NULL on failure.

Definition at line 176 of file io.c.

References io_rec::callback, io_rec::data, pollfd::events, pollfd::fd, io_context::fdcnt, io_context::fds, and io_context::ior.

00177 { 00178 if (*id < ioc->fdcnt) { 00179 if (fd > -1) 00180 ioc->fds[*id].fd = fd; 00181 if (callback) 00182 ioc->ior[*id].callback = callback; 00183 if (events) 00184 ioc->fds[*id].events = events; 00185 if (data) 00186 ioc->ior[*id].data = data; 00187 return id; 00188 } else return NULL; 00189 }

void ast_io_dump struct io_context ioc  ) 
 

Dumps the IO array.

Definition at line 281 of file io.c.

References ast_log(), io_rec::callback, io_rec::data, pollfd::events, pollfd::fd, io_context::fdcnt, io_context::fds, io_rec::id, io_context::ior, LOG_DEBUG, and io_context::maxfdcnt.

00282 { 00283 /* 00284 * Print some debugging information via 00285 * the logger interface 00286 */ 00287 int x; 00288 ast_log(LOG_DEBUG, "Asterisk IO Dump: %d entries, %d max entries\n", ioc->fdcnt, ioc->maxfdcnt); 00289 ast_log(LOG_DEBUG, "================================================\n"); 00290 ast_log(LOG_DEBUG, "| ID FD Callback Data Events |\n"); 00291 ast_log(LOG_DEBUG, "+------+------+-----------+-----------+--------+\n"); 00292 for (x=0;x<ioc->fdcnt;x++) { 00293 ast_log(LOG_DEBUG, "| %.4d | %.4d | %p | %p | %.6x |\n", 00294 *ioc->ior[x].id, 00295 ioc->fds[x].fd, 00296 ioc->ior[x].callback, 00297 ioc->ior[x].data, 00298 ioc->fds[x].events); 00299 } 00300 ast_log(LOG_DEBUG, "================================================\n"); 00301 }

int ast_io_remove struct io_context ioc,
int *  id
 

Removes an IO context.

Parameters:
ioc which io_context to remove it from
id which ID to remove Remove an I/O id from consideration Returns 0 on success or -1 on failure.

Definition at line 218 of file io.c.

References ast_log(), io_context::current_ioc, pollfd::events, io_context::fdcnt, io_context::fds, free, io_rec::id, io_context::ior, LOG_NOTICE, LOG_WARNING, io_context::needshrink, and pollfd::revents.

Referenced by ast_io_wait(), and ast_rtp_destroy().

00219 { 00220 int x; 00221 if (!_id) { 00222 ast_log(LOG_WARNING, "Asked to remove NULL?\n"); 00223 return -1; 00224 } 00225 for (x=0;x<ioc->fdcnt;x++) { 00226 if (ioc->ior[x].id == _id) { 00227 /* Free the int immediately and set to NULL so we know it's unused now */ 00228 free(ioc->ior[x].id); 00229 ioc->ior[x].id = NULL; 00230 ioc->fds[x].events = 0; 00231 ioc->fds[x].revents = 0; 00232 ioc->needshrink = 1; 00233 if (!ioc->current_ioc) 00234 io_shrink(ioc); 00235 return 0; 00236 } 00237 } 00238 00239 ast_log(LOG_NOTICE, "Unable to remove unknown id %p\n", _id); 00240 return -1; 00241 }

int ast_io_wait struct io_context ioc,
int  howlong
 

Waits for IO.

Parameters:
ioc which context to act upon
howlong how many milliseconds to wait Wait for I/O to happen, returning after howlong milliseconds, and after processing any necessary I/O. Returns the number of I/O events which took place.

Definition at line 243 of file io.c.

References ast_io_remove(), ast_log(), io_rec::callback, io_context::current_ioc, io_rec::data, DEBUG, pollfd::fd, io_context::fdcnt, io_context::fds, io_rec::id, io_context::ior, LOG_DEBUG, io_context::needshrink, poll(), and pollfd::revents.

00244 { 00245 /* 00246 * Make the poll call, and call 00247 * the callbacks for anything that needs 00248 * to be handled 00249 */ 00250 int res; 00251 int x; 00252 int origcnt; 00253 DEBUG(ast_log(LOG_DEBUG, "ast_io_wait()\n")); 00254 res = poll(ioc->fds, ioc->fdcnt, howlong); 00255 if (res > 0) { 00256 /* 00257 * At least one event 00258 */ 00259 origcnt = ioc->fdcnt; 00260 for(x=0;x<origcnt;x++) { 00261 /* Yes, it is possible for an entry to be deleted and still have an 00262 event waiting if it occurs after the original calling id */ 00263 if (ioc->fds[x].revents && ioc->ior[x].id) { 00264 /* There's an event waiting */ 00265 ioc->current_ioc = *ioc->ior[x].id; 00266 if (ioc->ior[x].callback) { 00267 if (!ioc->ior[x].callback(ioc->ior[x].id, ioc->fds[x].fd, ioc->fds[x].revents, ioc->ior[x].data)) { 00268 /* Time to delete them since they returned a 0 */ 00269 ast_io_remove(ioc, ioc->ior[x].id); 00270 } 00271 } 00272 ioc->current_ioc = -1; 00273 } 00274 } 00275 if (ioc->needshrink) 00276 io_shrink(ioc); 00277 } 00278 return res; 00279 }

int ast_restore_tty int  fd,
int  oldstate
 

Restores TTY mode.

Definition at line 324 of file io.c.

00325 { 00326 int res; 00327 struct termios tios; 00328 if (oldstate < 0) 00329 return 0; 00330 res = tcgetattr(fd, &tios); 00331 if (res < 0) 00332 return -1; 00333 tios.c_lflag &= ~(ECHO | ECHONL); 00334 tios.c_lflag |= oldstate; 00335 res = tcsetattr(fd, TCSAFLUSH, &tios); 00336 if (res < 0) 00337 return -1; 00338 return 0; 00339 }

struct io_context* io_context_create void   ) 
 

Creates a context.

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

Definition at line 65 of file io.c.

References free, GROW_SHRINK_SIZE, and malloc.

00066 { 00067 /* Create an I/O context */ 00068 struct io_context *tmp; 00069 tmp = malloc(sizeof(struct io_context)); 00070 if (tmp) { 00071 tmp->needshrink = 0; 00072 tmp->fdcnt = 0; 00073 tmp->maxfdcnt = GROW_SHRINK_SIZE/2; 00074 tmp->current_ioc = -1; 00075 tmp->fds = malloc((GROW_SHRINK_SIZE/2) * sizeof(struct pollfd)); 00076 if (!tmp->fds) { 00077 free(tmp); 00078 tmp = NULL; 00079 } else { 00080 memset(tmp->fds, 0, (GROW_SHRINK_SIZE/2) * sizeof(struct pollfd)); 00081 tmp->ior = malloc((GROW_SHRINK_SIZE/2) * sizeof(struct io_rec)); 00082 if (!tmp->ior) { 00083 free(tmp->fds); 00084 free(tmp); 00085 tmp = NULL; 00086 } else 00087 memset(tmp->ior, 0, (GROW_SHRINK_SIZE/2) * sizeof(struct io_rec)); 00088 } 00089 } 00090 return tmp; 00091 }

void io_context_destroy struct io_context ioc  ) 
 

Destroys a context.

Definition at line 93 of file io.c.

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

00094 { 00095 /* Free associated memory with an I/O context */ 00096 if (ioc->fds) 00097 free(ioc->fds); 00098 if (ioc->ior) 00099 free(ioc->ior); 00100 free(ioc); 00101 }


Generated on Sat Jun 12 16:41:36 2004 for Asterisk by doxygen 1.3.7