From 421263d049f0a4bfc4dca658db3e8bd4df480eec Mon Sep 17 00:00:00 2001 From: tholo Date: Sun, 26 Oct 2003 19:17:28 +0000 Subject: Make it build and run on MacOS X git-svn-id: http://svn.digium.com/svn/asterisk/trunk@1674 f38db490-d61c-443f-a65b-d21fe96a405b --- poll.c | 306 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 306 insertions(+) create mode 100755 poll.c (limited to 'poll.c') diff --git a/poll.c b/poll.c new file mode 100755 index 000000000..7a9d14e7a --- /dev/null +++ b/poll.c @@ -0,0 +1,306 @@ +/*---------------------------------------------------------------------------*\ + $Id$ + + NAME + + poll - select(2)-based poll() emulation function for BSD systems. + + SYNOPSIS + #include "poll.h" + + struct pollfd + { + int fd; + short events; + short revents; + } + + int poll (struct pollfd *pArray, unsigned long n_fds, int timeout) + + DESCRIPTION + + This file, and the accompanying "poll.h", implement the System V + poll(2) system call for BSD systems (which typically do not provide + poll()). Poll() provides a method for multiplexing input and output + on multiple open file descriptors; in traditional BSD systems, that + capability is provided by select(). While the semantics of select() + differ from those of poll(), poll() can be readily emulated in terms + of select() -- which is how this function is implemented. + + REFERENCES + Stevens, W. Richard. Unix Network Programming. Prentice-Hall, 1990. + + NOTES + 1. This software requires an ANSI C compiler. + + LICENSE + + This software is released under the following license: + + Copyright (c) 1995-2002 Brian M. Clapper + All rights reserved. + + Redistribution and use in source and binary forms are + permitted provided that: (1) source distributions retain + this entire copyright notice and comment; (2) modifications + made to the software are prominently mentioned, and a copy + of the original software (or a pointer to its location) are + included; and (3) distributions including binaries display + the following acknowledgement: "This product includes + software developed by Brian M. Clapper " + in the documentation or other materials provided with the + distribution. The name of the author may not be used to + endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + PARTICULAR PURPOSE. + + Effectively, this means you can do what you want with the software + except remove this notice or take advantage of the author's name. + If you modify the software and redistribute your modified version, + you must indicate that your version is a modification of the + original, and you must provide either a pointer to or a copy of the + original. +\*---------------------------------------------------------------------------*/ + + +/*---------------------------------------------------------------------------*\ + Includes +\*---------------------------------------------------------------------------*/ + +#include /* standard Unix definitions */ +#include /* system types */ +#include /* time definitions */ +#include /* assertion macros */ +#include /* string functions */ + +#include /* this package */ + +/*---------------------------------------------------------------------------*\ + Macros +\*---------------------------------------------------------------------------*/ + +#ifndef MAX +#define MAX(a,b) ((a) > (b) ? (a) : (b)) +#endif + + +/*---------------------------------------------------------------------------*\ + Private Functions +\*---------------------------------------------------------------------------*/ + +static int map_poll_spec +#if __STDC__ > 0 + (struct pollfd *pArray, + unsigned long n_fds, + fd_set *pReadSet, + fd_set *pWriteSet, + fd_set *pExceptSet) +#else + (pArray, n_fds, pReadSet, pWriteSet, pExceptSet) + struct pollfd *pArray; + unsigned long n_fds; + fd_set *pReadSet; + fd_set *pWriteSet; + fd_set *pExceptSet; +#endif +{ + register unsigned long i; /* loop control */ + register struct pollfd *pCur; /* current array element */ + register int max_fd = -1; /* return value */ + + /* + Map the poll() structures into the file descriptor sets required + by select(). + */ + for (i = 0, pCur = pArray; i < n_fds; i++, pCur++) + { + /* Skip any bad FDs in the array. */ + + if (pCur->fd < 0) + continue; + + if (pCur->events & POLLIN) + { + /* "Input Ready" notification desired. */ + FD_SET (pCur->fd, pReadSet); + } + + if (pCur->events & POLLOUT) + { + /* "Output Possible" notification desired. */ + FD_SET (pCur->fd, pWriteSet); + } + + if (pCur->events & POLLPRI) + { + /* + "Exception Occurred" notification desired. (Exceptions + include out of band data. + */ + FD_SET (pCur->fd, pExceptSet); + } + + max_fd = MAX (max_fd, pCur->fd); + } + + return max_fd; +} + +static struct timeval *map_timeout +#if __STDC__ > 0 + (int poll_timeout, struct timeval *pSelTimeout) +#else + (poll_timeout, pSelTimeout) + int poll_timeout; + struct timeval *pSelTimeout; +#endif +{ + struct timeval *pResult; + + /* + Map the poll() timeout value into a select() timeout. The possible + values of the poll() timeout value, and their meanings, are: + + VALUE MEANING + + -1 wait indefinitely (until signal occurs) + 0 return immediately, don't block + >0 wait specified number of milliseconds + + select() uses a "struct timeval", which specifies the timeout in + seconds and microseconds, so the milliseconds value has to be mapped + accordingly. + */ + + assert (pSelTimeout != (struct timeval *) NULL); + + switch (poll_timeout) + { + case -1: + /* + A NULL timeout structure tells select() to wait indefinitely. + */ + pResult = (struct timeval *) NULL; + break; + + case 0: + /* + "Return immediately" (test) is specified by all zeros in + a timeval structure. + */ + pSelTimeout->tv_sec = 0; + pSelTimeout->tv_usec = 0; + pResult = pSelTimeout; + break; + + default: + /* Wait the specified number of milliseconds. */ + pSelTimeout->tv_sec = poll_timeout / 1000; /* get seconds */ + poll_timeout %= 1000; /* remove seconds */ + pSelTimeout->tv_usec = poll_timeout * 1000; /* get microseconds */ + pResult = pSelTimeout; + break; + } + + + return pResult; +} + +static void map_select_results +#if __STDC__ > 0 + (struct pollfd *pArray, + unsigned long n_fds, + fd_set *pReadSet, + fd_set *pWriteSet, + fd_set *pExceptSet) +#else + (pArray, n_fds, pReadSet, pWriteSet, pExceptSet) + struct pollfd *pArray; + unsigned long n_fds; + fd_set *pReadSet; + fd_set *pWriteSet; + fd_set *pExceptSet; +#endif +{ + register unsigned long i; /* loop control */ + register struct pollfd *pCur; /* current array element */ + + for (i = 0, pCur = pArray; i < n_fds; i++, pCur++) + { + /* Skip any bad FDs in the array. */ + + if (pCur->fd < 0) + continue; + + /* Exception events take priority over input events. */ + + pCur->revents = 0; + if (FD_ISSET (pCur->fd, pExceptSet)) + pCur->revents |= POLLPRI; + + else if (FD_ISSET (pCur->fd, pReadSet)) + pCur->revents |= POLLIN; + + if (FD_ISSET (pCur->fd, pWriteSet)) + pCur->revents |= POLLOUT; + } + + return; +} + +/*---------------------------------------------------------------------------*\ + Public Functions +\*---------------------------------------------------------------------------*/ + +int poll + +#if __STDC__ > 0 + (struct pollfd *pArray, unsigned long n_fds, int timeout) +#else + (pArray, n_fds, timeout) + struct pollfd *pArray; + unsigned long n_fds; + int timeout; +#endif + +{ + fd_set read_descs; /* input file descs */ + fd_set write_descs; /* output file descs */ + fd_set except_descs; /* exception descs */ + struct timeval stime; /* select() timeout value */ + int ready_descriptors; /* function result */ + int max_fd; /* maximum fd value */ + struct timeval *pTimeout; /* actually passed */ + + FD_ZERO (&read_descs); + FD_ZERO (&write_descs); + FD_ZERO (&except_descs); + + assert (pArray != (struct pollfd *) NULL); + + /* Map the poll() file descriptor list in the select() data structures. */ + + max_fd = map_poll_spec (pArray, n_fds, + &read_descs, &write_descs, &except_descs); + + /* Map the poll() timeout value in the select() timeout structure. */ + + pTimeout = map_timeout (timeout, &stime); + + /* Make the select() call. */ + + ready_descriptors = select (max_fd + 1, &read_descs, &write_descs, + &except_descs, pTimeout); + + if (ready_descriptors >= 0) + { + map_select_results (pArray, n_fds, + &read_descs, &write_descs, &except_descs); + } + + return ready_descriptors; +} -- cgit v1.2.3