mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-10-31 18:55:19 +00:00 
			
		
		
		
	Make it build and run on MacOS X
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@1674 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
		
							
								
								
									
										306
									
								
								poll.c
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										306
									
								
								poll.c
									
									
									
									
									
										Executable file
									
								
							| @@ -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 <bmc@clapper.org>" | ||||
| 		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 <unistd.h>			     /* standard Unix definitions */ | ||||
| #include <sys/types.h>                       /* system types */ | ||||
| #include <sys/time.h>                        /* time definitions */ | ||||
| #include <assert.h>                          /* assertion macros */ | ||||
| #include <string.h>                          /* string functions */ | ||||
|  | ||||
| #include <asterisk/poll-compat.h>                            /* 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; | ||||
| } | ||||
		Reference in New Issue
	
	Block a user